@tearleads/client-sdk 0.1.39 → 0.1.41
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/client/organizations/organizationGroupPresentation.d.ts +1 -12
- package/data/documents/shared/syncResponses.js +5 -7
- package/data/documents/shared/syncResponses.js.map +1 -1
- package/data/persistence/organizations/organizationReadModelGrantPersistence.js +2 -1
- package/data/persistence/organizations/organizationReadModelGrantPersistence.js.map +1 -1
- package/data/persistence/organizations/organizationReadModelMemberLoad.d.ts +9 -0
- package/data/persistence/organizations/organizationReadModelMemberLoad.js +29 -21
- package/data/persistence/organizations/organizationReadModelMemberLoad.js.map +1 -1
- package/data/persistence/organizations/organizationReadModelMembershipPersistence.js +91 -46
- package/data/persistence/organizations/organizationReadModelMembershipPersistence.js.map +1 -1
- package/data/persistence/organizations/organizationReadModelPersistence.js +95 -73
- package/data/persistence/organizations/organizationReadModelPersistence.js.map +1 -1
- package/data/persistence/organizations/organizationReadModelProjection.js +78 -89
- package/data/persistence/organizations/organizationReadModelProjection.js.map +1 -1
- package/data/persistence/organizations/organizationReadModelPurge.js +14 -15
- package/data/persistence/organizations/organizationReadModelPurge.js.map +1 -1
- package/data/sqlite/organizationReadModelSchema.js +23 -28
- package/data/sqlite/organizationReadModelSchema.js.map +1 -1
- package/data/sqlite/organizationReadModelTableRegistry.d.ts +116 -263
- package/data/sqlite/organizationReadModelTableRegistry.js +10 -7
- package/data/sqlite/organizationReadModelTableRegistry.js.map +1 -1
- package/data/sqlite/schema.d.ts +116 -263
- package/data/sqlite/sqliteBindBudget.js +30 -0
- package/data/sqlite/sqliteBindBudget.js.map +1 -0
- package/internal/validators/documentSyncRefinements.js +5 -0
- package/internal/validators/documentSyncRefinements.js.map +1 -1
- package/internal/validators/operation/documentSync.d.ts +3 -0
- package/internal/validators/operation/organizations.d.ts +0 -16
- package/internal/validators/response/documentSyncSchema.js +35 -1
- package/internal/validators/response/documentSyncSchema.js.map +1 -1
- package/internal/validators/response/index.d.ts +1 -1
- package/internal/validators/response/index.js.map +1 -1
- package/internal/validators/response/organizationReadModel.d.ts +10 -48
- package/internal/validators/response/organizationReadModel.js +9 -1
- package/internal/validators/response/organizationReadModel.js.map +1 -1
- package/package.json +1 -1
- package/workflows/documents/syncContentKeys.js +4 -9
- package/workflows/documents/syncContentKeys.js.map +1 -1
- package/workflows/organizations/readModel.d.ts +8 -3
- package/workflows/organizations/readModel.js.map +1 -1
- package/workflows/organizations/readModelProjection.d.ts +2 -12
- package/workflows/organizations/readModelProjection.js +1 -1
- package/workflows/organizations/readModelProjection.js.map +1 -1
- package/workflows/sync/remoteReset.js +1 -3
- package/workflows/sync/remoteReset.js.map +1 -1
- package/data/persistence/organizations/organizationReadModelPolicyHeadPersistence.js +0 -64
- package/data/persistence/organizations/organizationReadModelPolicyHeadPersistence.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readModel.js","sourceRoot":"","sources":["readModel.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"readModel.js","sourceRoot":"","sources":["readModel.ts"],"names":[],"mappings":"AA8BA,OAAO,EACL,mCAAmC,EACnC,8BAA8B,GAC/B,MAAM,0BAA0B,CAAC;AAqElC,MAAM,CAAC,KAAK,UAAU,6BAA6B,CAAC,KAQnD;IACC,OAAO,KAAK,CAAC,SAAS,CAAC,6BAA6B,CAClD,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,MAAM,EACZ,EAAE,iBAAiB,EAAE,KAAK,CAAC,iBAAiB,EAAE,CAC/C,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,KAI/C;IACC,OAAO,KAAK,CAAC,SAAS,CAAC,yBAAyB,CAAC,KAAK,CAAC,cAAc,EAAE;QACrE,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;KAC3C,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type {\n UpdateOrganizationProfileRequest,\n UpdateOrganizationRosterEntryRequest,\n} from \"@tearleads/validators/request\";\nimport type {\n OrganizationContainerGrantResponse,\n OrganizationContainerGrantsResponse,\n OrganizationDirectoryResponse,\n OrganizationDirectoryUserResponse,\n OrganizationGroupContainerResponse,\n OrganizationGroupContainersResponse,\n OrganizationGroupSummaryResponse,\n OrganizationProfileResponse,\n OrganizationReadModelGroupMemberResponse,\n OrganizationUserDetailResponse,\n} from \"@tearleads/validators/response\";\nimport type { OrganizationGroupPolicyHistory } from \"./policyHistoryReadModel\";\n\nexport type {\n OrganizationGroupPolicyHistory,\n OrganizationGroupPolicyHistoryEntry,\n OrganizationPolicyGrantChange,\n OrganizationPolicyGroupChange,\n OrganizationPolicyHistory,\n OrganizationPolicyHistoryEntry,\n OrganizationPrincipalMemberChange,\n OrganizationPrincipalMemberChangeType,\n OrganizationPrincipalPolicyHistory,\n OrganizationPrincipalPolicyHistoryEntry,\n} from \"./policyHistoryReadModel\";\nexport {\n buildOrganizationGroupPolicyHistory,\n buildOrganizationPolicyHistory,\n} from \"./policyHistoryReadModel\";\n\nexport type OrganizationDirectory = OrganizationDirectoryResponse;\nexport type OrganizationDirectoryUser = OrganizationDirectoryUserResponse;\nexport type OrganizationProfile = OrganizationProfileResponse;\nexport type OrganizationGroupContainer = OrganizationGroupContainerResponse & {\n readonly containerDisplayName: string | null;\n};\nexport type OrganizationContainerGrant = OrganizationContainerGrantResponse & {\n readonly groupName: string | null;\n readonly containerDisplayName: string | null;\n};\nexport interface OrganizationGroupContainers\n extends Omit<OrganizationGroupContainersResponse, \"containers\"> {\n readonly containers: OrganizationGroupContainer[];\n}\nexport interface OrganizationContainerGrants\n extends Omit<OrganizationContainerGrantsResponse, \"grants\"> {\n readonly grants: OrganizationContainerGrant[];\n}\nexport interface OrganizationUserDetail\n extends Omit<OrganizationUserDetailResponse, \"grants\" | \"groups\"> {\n readonly groups: OrganizationGroupSummary[];\n readonly grants: {\n readonly directGrants: OrganizationContainerGrant[];\n readonly groupGrants: OrganizationContainerGrant[];\n };\n}\n/** A projected group member: public keys live in the directory lane only. */\nexport type OrganizationGroupMember = OrganizationReadModelGroupMemberResponse;\nexport interface OrganizationGroupMembers {\n readonly groupId: string;\n readonly members: OrganizationGroupMember[];\n readonly organizationId: string;\n}\nexport type OrganizationGroupSummary = OrganizationGroupSummaryResponse & {\n readonly name: string;\n /**\n * The group's signed name does not open under the metadata key this member\n * holds; only a dishonest admin signs such a name. `name` is then empty, and\n * the group must not be offered for selection by name.\n */\n readonly nameUnreadable: boolean;\n};\nexport interface OrganizationDirectoryAndGroups {\n readonly directory: OrganizationDirectory;\n readonly groups: ReadonlyArray<OrganizationGroupSummary>;\n readonly memberGroupId: string;\n readonly readModelCursor: string;\n}\n\nexport interface OrganizationGroupDetails {\n readonly members: OrganizationGroupMembers | null;\n readonly containers: OrganizationGroupContainers | null;\n readonly policyHistory: OrganizationGroupPolicyHistory | null;\n}\n\ninterface OrganizationReadApi {\n readonly updateOrganizationRosterEntry: (\n organizationId: string,\n userId: string,\n input: UpdateOrganizationRosterEntryRequest,\n ) => Promise<OrganizationDirectoryUserResponse | null>;\n readonly updateOrganizationProfile: (\n organizationId: string,\n input: UpdateOrganizationProfileRequest,\n ) => Promise<OrganizationProfileResponse | null>;\n}\n\nexport async function updateOrganizationRosterEntry(input: {\n readonly apiClient: Pick<\n OrganizationReadApi,\n \"updateOrganizationRosterEntry\"\n >;\n readonly organizationId: string;\n readonly profileDocumentId: string | null;\n readonly userId: string;\n}): Promise<OrganizationDirectoryUser | null> {\n return input.apiClient.updateOrganizationRosterEntry(\n input.organizationId,\n input.userId,\n { profileDocumentId: input.profileDocumentId },\n );\n}\n\nexport async function updateOrganizationProfile(input: {\n readonly apiClient: Pick<OrganizationReadApi, \"updateOrganizationProfile\">;\n readonly organizationId: string;\n readonly profileDocumentId: string | null;\n}): Promise<OrganizationProfileResponse | null> {\n return input.apiClient.updateOrganizationProfile(input.organizationId, {\n profileDocumentId: input.profileDocumentId,\n });\n}\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { RequestResult, RequestResultOptions } from "../../internal/api-client/index.js";
|
|
2
2
|
import { type OrganizationReadModelResponse } from "../../internal/validators/response/index.js";
|
|
3
|
+
import { type OrganizationReadModelGroupMembers } from "../../data/persistence/organizations/organizationReadModelMemberLoad.js";
|
|
3
4
|
import type { ExecSql } from "../../data/sqlite/sqlSchema.js";
|
|
4
5
|
import type { OrganizationDirectoryAndGroups } from "./readModel.js";
|
|
5
6
|
interface OrganizationReadModelApi {
|
|
@@ -17,18 +18,7 @@ export interface ReconcileOrganizationDirectoryAndGroupsInput extends Organizati
|
|
|
17
18
|
export declare function loadLocalOrganizationDirectoryAndGroups(input: OrganizationReadModelProjectionInput): Promise<OrganizationDirectoryAndGroups | null>;
|
|
18
19
|
export declare function loadLocalOrganizationGroupMembers(input: OrganizationReadModelProjectionInput & {
|
|
19
20
|
readonly groupId: string;
|
|
20
|
-
}): Promise<
|
|
21
|
-
groupId: string;
|
|
22
|
-
members: {
|
|
23
|
-
encapsulationKeyFingerprint: string | null;
|
|
24
|
-
encapsulationPublicKey: string | null;
|
|
25
|
-
role: "member" | "admin";
|
|
26
|
-
signingKeyFingerprint: string | null;
|
|
27
|
-
signingPublicKey: string | null;
|
|
28
|
-
userId: string;
|
|
29
|
-
}[];
|
|
30
|
-
organizationId: string;
|
|
31
|
-
} | null>;
|
|
21
|
+
}): Promise<OrganizationReadModelGroupMembers | null>;
|
|
32
22
|
/**
|
|
33
23
|
* Resolves the reconciled projection, `null` when the pass completed
|
|
34
24
|
* authoritatively with nothing presentable (including a denial that purged
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ORGANIZATION_READ_MODEL_ERROR_CODES, } from "../../internal/validators/response/index.js";
|
|
2
2
|
import { purgeOrganizationAccessProjection } from "../../data/persistence/organizations/organizationAccessRevocationPersistence.js";
|
|
3
3
|
import { recordOrganizationPresentationDenials } from "../../data/persistence/organizations/organizationPresentationDenialPersistence.js";
|
|
4
|
-
import { loadOrganizationReadModelGroupMembers } from "../../data/persistence/organizations/organizationReadModelMemberLoad.js";
|
|
4
|
+
import { loadOrganizationReadModelGroupMembers, } from "../../data/persistence/organizations/organizationReadModelMemberLoad.js";
|
|
5
5
|
import { OrganizationReadModelBindingError } from "../../data/persistence/organizations/organizationReadModelMembershipPersistence.js";
|
|
6
6
|
import { applyOrganizationReadModelResponse, loadOrganizationReadModelProjection, purgeOrganizationReadModelProjection, } from "../../data/persistence/organizations/organizationReadModelPersistence.js";
|
|
7
7
|
import { captureOrganizationPresentationAccessAttempt, denyOrganizationPresentationAccess, isOrganizationPresentationAccessAttemptCurrent, isOrganizationPresentationAccessReadable, restoreOrganizationPresentationAccess, runOrganizationPresentationMutation, runOrganizationPresentationRead, } from "./organizationPresentationAccessState.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readModelProjection.js","sourceRoot":"","sources":["readModelProjection.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n RequestResult,\n RequestResultOptions,\n} from \"@tearleads/api-client\";\nimport {\n ORGANIZATION_READ_MODEL_ERROR_CODES,\n type OrganizationReadModelResponse,\n} from \"@tearleads/validators/response\";\nimport { purgeOrganizationAccessProjection } from \"../../data/persistence/organizations/organizationAccessRevocationPersistence\";\nimport { recordOrganizationPresentationDenials } from \"../../data/persistence/organizations/organizationPresentationDenialPersistence\";\nimport { loadOrganizationReadModelGroupMembers } from \"../../data/persistence/organizations/organizationReadModelMemberLoad\";\nimport { OrganizationReadModelBindingError } from \"../../data/persistence/organizations/organizationReadModelMembershipPersistence\";\nimport {\n applyOrganizationReadModelResponse,\n loadOrganizationReadModelProjection,\n type OrganizationReadModelProjection,\n purgeOrganizationReadModelProjection,\n} from \"../../data/persistence/organizations/organizationReadModelPersistence\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport {\n captureOrganizationPresentationAccessAttempt,\n denyOrganizationPresentationAccess,\n isOrganizationPresentationAccessAttemptCurrent,\n isOrganizationPresentationAccessReadable,\n type OrganizationPresentationAccessAttempt,\n type OrganizationPresentationAccessInput,\n restoreOrganizationPresentationAccess,\n runOrganizationPresentationMutation,\n runOrganizationPresentationRead,\n} from \"./organizationPresentationAccessState\";\nimport { isOrganizationPresentationAccessDeniedFailure } from \"./organizationPresentationFailures\";\nimport type { OrganizationDirectoryAndGroups } from \"./readModel\";\n\nconst MAX_READ_MODEL_PAGES = 100;\nconst MAX_STALE_RETRIES = 1;\n\ninterface OrganizationReadModelApi {\n getOrganizationReadModelResult(\n organizationId: string,\n cursor?: string,\n options?: RequestResultOptions,\n ): Promise<RequestResult<OrganizationReadModelResponse>>;\n}\n\ninterface OrganizationReadModelProjectionInput {\n readonly currentUserId: string;\n readonly execSql: ExecSql;\n readonly organizationId: string;\n}\n\nexport interface ReconcileOrganizationDirectoryAndGroupsInput\n extends OrganizationReadModelProjectionInput {\n readonly apiClient: OrganizationReadModelApi;\n readonly logError?:\n | ((message: string | Error, cause?: unknown) => void)\n | undefined;\n}\n\nfunction toDirectoryAndGroups(\n projection: OrganizationReadModelProjection | null,\n): OrganizationDirectoryAndGroups | null {\n if (!projection?.requester) {\n return null;\n }\n\n return {\n directory: {\n ...projection.directory,\n currentUser: projection.requester,\n },\n // Hydration decides whether a name is unreadable; a stored blank name may\n // only mean the group has not been hydrated yet.\n groups: projection.groups.groups.map((group) => ({\n ...group,\n nameUnreadable: false,\n })),\n memberGroupId: projection.groups.memberGroupId,\n readModelCursor: projection.cursor,\n };\n}\n\nasync function loadProjection(\n input: OrganizationReadModelProjectionInput,\n): Promise<OrganizationReadModelProjection | null> {\n return runOrganizationPresentationRead(\n organizationPresentationAccessInput(input),\n \"readModel\",\n () => loadRawProjection(input),\n );\n}\n\nfunction loadRawProjection(\n input: OrganizationReadModelProjectionInput,\n): Promise<OrganizationReadModelProjection | null> {\n return loadOrganizationReadModelProjection(\n input.execSql,\n input.organizationId,\n input.currentUserId,\n );\n}\n\nfunction organizationPresentationAccessInput(\n input: OrganizationReadModelProjectionInput,\n): OrganizationPresentationAccessInput {\n return {\n execSql: input.execSql,\n organizationId: input.organizationId,\n requesterUserId: input.currentUserId,\n };\n}\n\ninterface ReconciliationState {\n readonly accessAttempt: OrganizationPresentationAccessAttempt;\n expectedLocalCursor: string | null;\n preparedDeniedProjection: boolean;\n projection: OrganizationReadModelProjection | null;\n requestCursor: string | undefined;\n retriedBindingFailure: boolean;\n retriedInvalidCursor: boolean;\n staleRetries: number;\n}\n\ntype ReconciliationStep =\n | { readonly kind: \"continue\" }\n | {\n readonly kind: \"done\";\n readonly value: OrganizationDirectoryAndGroups | null | undefined;\n };\n\ntype PageRequestStep =\n | ReconciliationStep\n | {\n readonly kind: \"response\";\n readonly response: OrganizationReadModelResponse;\n };\n\nfunction localResult(\n input: ReconcileOrganizationDirectoryAndGroupsInput,\n state: ReconciliationState,\n outcome: { readonly failed: boolean },\n): ReconciliationStep {\n const accessInput = organizationPresentationAccessInput(input);\n const readable =\n isOrganizationPresentationAccessAttemptCurrent(\n accessInput,\n state.accessAttempt,\n ) && isOrganizationPresentationAccessReadable(accessInput, \"readModel\");\n if (!readable) {\n return { kind: \"done\", value: null };\n }\n const value = toDirectoryAndGroups(state.projection);\n // A failed pass that retained nothing must not read as a completed (null)\n // pass: consumers mark a scope caught up only on completed passes, and this\n // scope still needs a fresh catch-up.\n if (value === null && outcome.failed) {\n return { kind: \"done\", value: undefined };\n }\n return { kind: \"done\", value };\n}\n\nfunction resetRequestCursor(state: ReconciliationState): void {\n state.expectedLocalCursor = state.projection?.cursor ?? null;\n state.requestCursor = state.projection?.cursor ?? undefined;\n}\n\nfunction isInvalidReadModelCursorFailure(\n result: RequestResult<OrganizationReadModelResponse>,\n): boolean {\n return (\n !result.ok &&\n result.kind === \"http\" &&\n result.status === 400 &&\n result.code === ORGANIZATION_READ_MODEL_ERROR_CODES.cursorInvalid\n );\n}\n\nasync function requestReadModelPage(\n input: ReconcileOrganizationDirectoryAndGroupsInput,\n state: ReconciliationState,\n): Promise<PageRequestStep> {\n const result = await input.apiClient.getOrganizationReadModelResult(\n input.organizationId,\n state.requestCursor,\n { reportErrors: false },\n );\n if (result.ok) {\n return { kind: \"response\", response: result.data };\n }\n if (isOrganizationPresentationAccessDeniedFailure(result)) {\n const accessInput = organizationPresentationAccessInput(input);\n denyOrganizationPresentationAccess(accessInput, [\"readModel\", \"usage\"]);\n // The durable marker lands before the purge attempt: if the purge fails,\n // an offline restart must still refuse to serve the revoked projection.\n try {\n await runOrganizationPresentationMutation(input.execSql, () =>\n recordOrganizationPresentationDenials(accessInput, [\n \"readModel\",\n \"usage\",\n ]),\n );\n } catch (error) {\n input.logError?.(\"Failed to record denied organization access\", error);\n }\n try {\n await runOrganizationPresentationMutation(input.execSql, () =>\n purgeOrganizationAccessProjection({\n execSql: input.execSql,\n organizationId: input.organizationId,\n requesterUserId: input.currentUserId,\n }),\n );\n } catch (error) {\n input.logError?.(\"Failed to purge denied organization access\", error);\n }\n return { kind: \"done\", value: null };\n }\n if (\n isInvalidReadModelCursorFailure(result) &&\n state.requestCursor !== undefined &&\n !state.retriedInvalidCursor\n ) {\n state.requestCursor = undefined;\n state.retriedInvalidCursor = true;\n return { kind: \"continue\" };\n }\n\n result.report();\n return localResult(input, state, { failed: true });\n}\n\nfunction responseMatchesRequest(\n input: ReconcileOrganizationDirectoryAndGroupsInput,\n state: ReconciliationState,\n response: OrganizationReadModelResponse,\n): boolean {\n if (response.organizationId !== input.organizationId) {\n input.logError?.(\n `Organization read-model response scope does not match ${input.organizationId}`,\n );\n return false;\n }\n if (response.hasMore && response.nextCursor === state.expectedLocalCursor) {\n input.logError?.(\"Organization read-model page did not advance its cursor\");\n return false;\n }\n return true;\n}\n\nfunction reconciliationIsCurrent(\n input: ReconcileOrganizationDirectoryAndGroupsInput,\n state: ReconciliationState,\n): boolean {\n return isOrganizationPresentationAccessAttemptCurrent(\n organizationPresentationAccessInput(input),\n state.accessAttempt,\n );\n}\n\ntype ApplyResponseStep =\n | ReconciliationStep\n | {\n readonly kind: \"applied\";\n readonly result: Awaited<\n ReturnType<typeof applyOrganizationReadModelResponse>\n >;\n };\n\nasync function applyResponse(\n input: ReconcileOrganizationDirectoryAndGroupsInput,\n state: ReconciliationState,\n response: OrganizationReadModelResponse,\n): Promise<ApplyResponseStep> {\n try {\n return {\n kind: \"applied\",\n result: await applyOrganizationReadModelResponse({\n currentUserId: input.currentUserId,\n execSql: input.execSql,\n requestedCursor: state.expectedLocalCursor,\n response,\n }),\n };\n } catch (error) {\n input.logError?.(\"Failed to apply organization read-model response\", error);\n if (\n !(error instanceof OrganizationReadModelBindingError) ||\n state.retriedBindingFailure\n ) {\n return localResult(input, state, { failed: true });\n }\n state.retriedBindingFailure = true;\n await purgeOrganizationReadModelProjection(\n input.execSql,\n input.organizationId,\n );\n if (!reconciliationIsCurrent(input, state)) {\n return { kind: \"done\", value: null };\n }\n state.projection = null;\n resetRequestCursor(state);\n return { kind: \"continue\" };\n }\n}\n\nasync function prepareDeniedProjectionForApply(\n input: ReconcileOrganizationDirectoryAndGroupsInput,\n state: ReconciliationState,\n): Promise<ReconciliationStep | null> {\n if (state.preparedDeniedProjection) {\n return null;\n }\n try {\n // The apply that follows replaces the shared rows authoritatively, so\n // only this requester's row is dropped: another local identity sharing\n // the database keeps its access and reads the replacement.\n await purgeOrganizationReadModelProjection(\n input.execSql,\n input.organizationId,\n { onlyRequesterUserId: input.currentUserId },\n );\n } catch (error) {\n input.logError?.(\"Failed to replace denied organization read model\", error);\n return { kind: \"done\", value: null };\n }\n if (!reconciliationIsCurrent(input, state)) {\n return { kind: \"done\", value: null };\n }\n state.expectedLocalCursor = null;\n state.preparedDeniedProjection = true;\n state.projection = null;\n return null;\n}\n\nasync function applyReadModelPage(\n input: ReconcileOrganizationDirectoryAndGroupsInput,\n state: ReconciliationState,\n response: OrganizationReadModelResponse,\n): Promise<ReconciliationStep> {\n if (!responseMatchesRequest(input, state, response)) {\n return localResult(input, state, { failed: true });\n }\n\n const accessInput = organizationPresentationAccessInput(input);\n return runOrganizationPresentationMutation(input.execSql, async () => {\n if (!reconciliationIsCurrent(input, state)) {\n return { kind: \"done\", value: null };\n }\n const preparation = await prepareDeniedProjectionForApply(input, state);\n if (preparation) {\n return preparation;\n }\n\n const applied = await applyResponse(input, state, response);\n if (applied.kind !== \"applied\") {\n return applied;\n }\n\n state.projection = await loadRawProjection(input);\n if (!reconciliationIsCurrent(input, state)) {\n return { kind: \"done\", value: null };\n }\n if (applied.result === \"stale\") {\n if (state.staleRetries >= MAX_STALE_RETRIES) {\n return localResult(input, state, { failed: true });\n }\n state.staleRetries += 1;\n resetRequestCursor(state);\n return { kind: \"continue\" };\n }\n\n state.expectedLocalCursor = state.projection?.cursor ?? response.nextCursor;\n if (!response.hasMore) {\n return restoreOrganizationPresentationAccess(\n accessInput,\n state.accessAttempt,\n )\n ? localResult(input, state, { failed: false })\n : { kind: \"done\", value: null };\n }\n state.requestCursor = response.nextCursor;\n return { kind: \"continue\" };\n });\n}\n\nexport async function loadLocalOrganizationDirectoryAndGroups(\n input: OrganizationReadModelProjectionInput,\n): Promise<OrganizationDirectoryAndGroups | null> {\n return toDirectoryAndGroups(await loadProjection(input));\n}\n\nexport async function loadLocalOrganizationGroupMembers(\n input: OrganizationReadModelProjectionInput & { readonly groupId: string },\n) {\n return runOrganizationPresentationRead(\n organizationPresentationAccessInput(input),\n \"readModel\",\n () =>\n loadOrganizationReadModelGroupMembers(\n input.execSql,\n input.organizationId,\n input.groupId,\n input.currentUserId,\n ),\n );\n}\n\n/**\n * Resolves the reconciled projection, `null` when the pass completed\n * authoritatively with nothing presentable (including a denial that purged\n * the projection), or `undefined` when the feed failed and no local\n * projection was retained — a pass that must not count as caught up.\n */\nexport async function reconcileOrganizationDirectoryAndGroups(\n input: ReconcileOrganizationDirectoryAndGroupsInput,\n): Promise<OrganizationDirectoryAndGroups | null | undefined> {\n const accessInput = organizationPresentationAccessInput(input);\n const accessAttempt = captureOrganizationPresentationAccessAttempt(\n accessInput,\n \"readModel\",\n );\n const state: ReconciliationState = {\n accessAttempt,\n expectedLocalCursor: null,\n preparedDeniedProjection: !accessAttempt.startedDenied,\n projection: await loadProjection(input),\n requestCursor: undefined,\n retriedBindingFailure: false,\n retriedInvalidCursor: false,\n staleRetries: 0,\n };\n resetRequestCursor(state);\n\n for (let page = 0; page < MAX_READ_MODEL_PAGES; page += 1) {\n const request = await requestReadModelPage(input, state);\n if (request.kind === \"done\") {\n return request.value;\n }\n if (request.kind === \"continue\") {\n continue;\n }\n const applied = await applyReadModelPage(input, state, request.response);\n if (applied.kind === \"done\") {\n return applied.value;\n }\n }\n\n input.logError?.(\n \"Organization read-model reconciliation exceeded page limit\",\n );\n const retained = localResult(input, state, { failed: true });\n return retained.kind === \"done\" ? retained.value : null;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"readModelProjection.js","sourceRoot":"","sources":["readModelProjection.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n RequestResult,\n RequestResultOptions,\n} from \"@tearleads/api-client\";\nimport {\n ORGANIZATION_READ_MODEL_ERROR_CODES,\n type OrganizationReadModelResponse,\n} from \"@tearleads/validators/response\";\nimport { purgeOrganizationAccessProjection } from \"../../data/persistence/organizations/organizationAccessRevocationPersistence\";\nimport { recordOrganizationPresentationDenials } from \"../../data/persistence/organizations/organizationPresentationDenialPersistence\";\nimport {\n loadOrganizationReadModelGroupMembers,\n type OrganizationReadModelGroupMembers,\n} from \"../../data/persistence/organizations/organizationReadModelMemberLoad\";\nimport { OrganizationReadModelBindingError } from \"../../data/persistence/organizations/organizationReadModelMembershipPersistence\";\nimport {\n applyOrganizationReadModelResponse,\n loadOrganizationReadModelProjection,\n type OrganizationReadModelProjection,\n purgeOrganizationReadModelProjection,\n} from \"../../data/persistence/organizations/organizationReadModelPersistence\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport {\n captureOrganizationPresentationAccessAttempt,\n denyOrganizationPresentationAccess,\n isOrganizationPresentationAccessAttemptCurrent,\n isOrganizationPresentationAccessReadable,\n type OrganizationPresentationAccessAttempt,\n type OrganizationPresentationAccessInput,\n restoreOrganizationPresentationAccess,\n runOrganizationPresentationMutation,\n runOrganizationPresentationRead,\n} from \"./organizationPresentationAccessState\";\nimport { isOrganizationPresentationAccessDeniedFailure } from \"./organizationPresentationFailures\";\nimport type { OrganizationDirectoryAndGroups } from \"./readModel\";\n\nconst MAX_READ_MODEL_PAGES = 100;\nconst MAX_STALE_RETRIES = 1;\n\ninterface OrganizationReadModelApi {\n getOrganizationReadModelResult(\n organizationId: string,\n cursor?: string,\n options?: RequestResultOptions,\n ): Promise<RequestResult<OrganizationReadModelResponse>>;\n}\n\ninterface OrganizationReadModelProjectionInput {\n readonly currentUserId: string;\n readonly execSql: ExecSql;\n readonly organizationId: string;\n}\n\nexport interface ReconcileOrganizationDirectoryAndGroupsInput\n extends OrganizationReadModelProjectionInput {\n readonly apiClient: OrganizationReadModelApi;\n readonly logError?:\n | ((message: string | Error, cause?: unknown) => void)\n | undefined;\n}\n\nfunction toDirectoryAndGroups(\n projection: OrganizationReadModelProjection | null,\n): OrganizationDirectoryAndGroups | null {\n if (!projection?.requester) {\n return null;\n }\n\n return {\n directory: {\n ...projection.directory,\n currentUser: projection.requester,\n },\n // Hydration decides whether a name is unreadable; a stored blank name may\n // only mean the group has not been hydrated yet.\n groups: projection.groups.groups.map((group) => ({\n ...group,\n nameUnreadable: false,\n })),\n memberGroupId: projection.groups.memberGroupId,\n readModelCursor: projection.cursor,\n };\n}\n\nasync function loadProjection(\n input: OrganizationReadModelProjectionInput,\n): Promise<OrganizationReadModelProjection | null> {\n return runOrganizationPresentationRead(\n organizationPresentationAccessInput(input),\n \"readModel\",\n () => loadRawProjection(input),\n );\n}\n\nfunction loadRawProjection(\n input: OrganizationReadModelProjectionInput,\n): Promise<OrganizationReadModelProjection | null> {\n return loadOrganizationReadModelProjection(\n input.execSql,\n input.organizationId,\n input.currentUserId,\n );\n}\n\nfunction organizationPresentationAccessInput(\n input: OrganizationReadModelProjectionInput,\n): OrganizationPresentationAccessInput {\n return {\n execSql: input.execSql,\n organizationId: input.organizationId,\n requesterUserId: input.currentUserId,\n };\n}\n\ninterface ReconciliationState {\n readonly accessAttempt: OrganizationPresentationAccessAttempt;\n expectedLocalCursor: string | null;\n preparedDeniedProjection: boolean;\n projection: OrganizationReadModelProjection | null;\n requestCursor: string | undefined;\n retriedBindingFailure: boolean;\n retriedInvalidCursor: boolean;\n staleRetries: number;\n}\n\ntype ReconciliationStep =\n | { readonly kind: \"continue\" }\n | {\n readonly kind: \"done\";\n readonly value: OrganizationDirectoryAndGroups | null | undefined;\n };\n\ntype PageRequestStep =\n | ReconciliationStep\n | {\n readonly kind: \"response\";\n readonly response: OrganizationReadModelResponse;\n };\n\nfunction localResult(\n input: ReconcileOrganizationDirectoryAndGroupsInput,\n state: ReconciliationState,\n outcome: { readonly failed: boolean },\n): ReconciliationStep {\n const accessInput = organizationPresentationAccessInput(input);\n const readable =\n isOrganizationPresentationAccessAttemptCurrent(\n accessInput,\n state.accessAttempt,\n ) && isOrganizationPresentationAccessReadable(accessInput, \"readModel\");\n if (!readable) {\n return { kind: \"done\", value: null };\n }\n const value = toDirectoryAndGroups(state.projection);\n // A failed pass that retained nothing must not read as a completed (null)\n // pass: consumers mark a scope caught up only on completed passes, and this\n // scope still needs a fresh catch-up.\n if (value === null && outcome.failed) {\n return { kind: \"done\", value: undefined };\n }\n return { kind: \"done\", value };\n}\n\nfunction resetRequestCursor(state: ReconciliationState): void {\n state.expectedLocalCursor = state.projection?.cursor ?? null;\n state.requestCursor = state.projection?.cursor ?? undefined;\n}\n\nfunction isInvalidReadModelCursorFailure(\n result: RequestResult<OrganizationReadModelResponse>,\n): boolean {\n return (\n !result.ok &&\n result.kind === \"http\" &&\n result.status === 400 &&\n result.code === ORGANIZATION_READ_MODEL_ERROR_CODES.cursorInvalid\n );\n}\n\nasync function requestReadModelPage(\n input: ReconcileOrganizationDirectoryAndGroupsInput,\n state: ReconciliationState,\n): Promise<PageRequestStep> {\n const result = await input.apiClient.getOrganizationReadModelResult(\n input.organizationId,\n state.requestCursor,\n { reportErrors: false },\n );\n if (result.ok) {\n return { kind: \"response\", response: result.data };\n }\n if (isOrganizationPresentationAccessDeniedFailure(result)) {\n const accessInput = organizationPresentationAccessInput(input);\n denyOrganizationPresentationAccess(accessInput, [\"readModel\", \"usage\"]);\n // The durable marker lands before the purge attempt: if the purge fails,\n // an offline restart must still refuse to serve the revoked projection.\n try {\n await runOrganizationPresentationMutation(input.execSql, () =>\n recordOrganizationPresentationDenials(accessInput, [\n \"readModel\",\n \"usage\",\n ]),\n );\n } catch (error) {\n input.logError?.(\"Failed to record denied organization access\", error);\n }\n try {\n await runOrganizationPresentationMutation(input.execSql, () =>\n purgeOrganizationAccessProjection({\n execSql: input.execSql,\n organizationId: input.organizationId,\n requesterUserId: input.currentUserId,\n }),\n );\n } catch (error) {\n input.logError?.(\"Failed to purge denied organization access\", error);\n }\n return { kind: \"done\", value: null };\n }\n if (\n isInvalidReadModelCursorFailure(result) &&\n state.requestCursor !== undefined &&\n !state.retriedInvalidCursor\n ) {\n state.requestCursor = undefined;\n state.retriedInvalidCursor = true;\n return { kind: \"continue\" };\n }\n\n result.report();\n return localResult(input, state, { failed: true });\n}\n\nfunction responseMatchesRequest(\n input: ReconcileOrganizationDirectoryAndGroupsInput,\n state: ReconciliationState,\n response: OrganizationReadModelResponse,\n): boolean {\n if (response.organizationId !== input.organizationId) {\n input.logError?.(\n `Organization read-model response scope does not match ${input.organizationId}`,\n );\n return false;\n }\n if (response.hasMore && response.nextCursor === state.expectedLocalCursor) {\n input.logError?.(\"Organization read-model page did not advance its cursor\");\n return false;\n }\n return true;\n}\n\nfunction reconciliationIsCurrent(\n input: ReconcileOrganizationDirectoryAndGroupsInput,\n state: ReconciliationState,\n): boolean {\n return isOrganizationPresentationAccessAttemptCurrent(\n organizationPresentationAccessInput(input),\n state.accessAttempt,\n );\n}\n\ntype ApplyResponseStep =\n | ReconciliationStep\n | {\n readonly kind: \"applied\";\n readonly result: Awaited<\n ReturnType<typeof applyOrganizationReadModelResponse>\n >;\n };\n\nasync function applyResponse(\n input: ReconcileOrganizationDirectoryAndGroupsInput,\n state: ReconciliationState,\n response: OrganizationReadModelResponse,\n): Promise<ApplyResponseStep> {\n try {\n return {\n kind: \"applied\",\n result: await applyOrganizationReadModelResponse({\n currentUserId: input.currentUserId,\n execSql: input.execSql,\n requestedCursor: state.expectedLocalCursor,\n response,\n }),\n };\n } catch (error) {\n input.logError?.(\"Failed to apply organization read-model response\", error);\n if (\n !(error instanceof OrganizationReadModelBindingError) ||\n state.retriedBindingFailure\n ) {\n return localResult(input, state, { failed: true });\n }\n state.retriedBindingFailure = true;\n await purgeOrganizationReadModelProjection(\n input.execSql,\n input.organizationId,\n );\n if (!reconciliationIsCurrent(input, state)) {\n return { kind: \"done\", value: null };\n }\n state.projection = null;\n resetRequestCursor(state);\n return { kind: \"continue\" };\n }\n}\n\nasync function prepareDeniedProjectionForApply(\n input: ReconcileOrganizationDirectoryAndGroupsInput,\n state: ReconciliationState,\n): Promise<ReconciliationStep | null> {\n if (state.preparedDeniedProjection) {\n return null;\n }\n try {\n // The apply that follows replaces the shared rows authoritatively, so\n // only this requester's row is dropped: another local identity sharing\n // the database keeps its access and reads the replacement.\n await purgeOrganizationReadModelProjection(\n input.execSql,\n input.organizationId,\n { onlyRequesterUserId: input.currentUserId },\n );\n } catch (error) {\n input.logError?.(\"Failed to replace denied organization read model\", error);\n return { kind: \"done\", value: null };\n }\n if (!reconciliationIsCurrent(input, state)) {\n return { kind: \"done\", value: null };\n }\n state.expectedLocalCursor = null;\n state.preparedDeniedProjection = true;\n state.projection = null;\n return null;\n}\n\nasync function applyReadModelPage(\n input: ReconcileOrganizationDirectoryAndGroupsInput,\n state: ReconciliationState,\n response: OrganizationReadModelResponse,\n): Promise<ReconciliationStep> {\n if (!responseMatchesRequest(input, state, response)) {\n return localResult(input, state, { failed: true });\n }\n\n const accessInput = organizationPresentationAccessInput(input);\n return runOrganizationPresentationMutation(input.execSql, async () => {\n if (!reconciliationIsCurrent(input, state)) {\n return { kind: \"done\", value: null };\n }\n const preparation = await prepareDeniedProjectionForApply(input, state);\n if (preparation) {\n return preparation;\n }\n\n const applied = await applyResponse(input, state, response);\n if (applied.kind !== \"applied\") {\n return applied;\n }\n\n state.projection = await loadRawProjection(input);\n if (!reconciliationIsCurrent(input, state)) {\n return { kind: \"done\", value: null };\n }\n if (applied.result === \"stale\") {\n if (state.staleRetries >= MAX_STALE_RETRIES) {\n return localResult(input, state, { failed: true });\n }\n state.staleRetries += 1;\n resetRequestCursor(state);\n return { kind: \"continue\" };\n }\n\n state.expectedLocalCursor = state.projection?.cursor ?? response.nextCursor;\n if (!response.hasMore) {\n return restoreOrganizationPresentationAccess(\n accessInput,\n state.accessAttempt,\n )\n ? localResult(input, state, { failed: false })\n : { kind: \"done\", value: null };\n }\n state.requestCursor = response.nextCursor;\n return { kind: \"continue\" };\n });\n}\n\nexport async function loadLocalOrganizationDirectoryAndGroups(\n input: OrganizationReadModelProjectionInput,\n): Promise<OrganizationDirectoryAndGroups | null> {\n return toDirectoryAndGroups(await loadProjection(input));\n}\n\nexport async function loadLocalOrganizationGroupMembers(\n input: OrganizationReadModelProjectionInput & { readonly groupId: string },\n): Promise<OrganizationReadModelGroupMembers | null> {\n return runOrganizationPresentationRead(\n organizationPresentationAccessInput(input),\n \"readModel\",\n () =>\n loadOrganizationReadModelGroupMembers(\n input.execSql,\n input.organizationId,\n input.groupId,\n input.currentUserId,\n ),\n );\n}\n\n/**\n * Resolves the reconciled projection, `null` when the pass completed\n * authoritatively with nothing presentable (including a denial that purged\n * the projection), or `undefined` when the feed failed and no local\n * projection was retained — a pass that must not count as caught up.\n */\nexport async function reconcileOrganizationDirectoryAndGroups(\n input: ReconcileOrganizationDirectoryAndGroupsInput,\n): Promise<OrganizationDirectoryAndGroups | null | undefined> {\n const accessInput = organizationPresentationAccessInput(input);\n const accessAttempt = captureOrganizationPresentationAccessAttempt(\n accessInput,\n \"readModel\",\n );\n const state: ReconciliationState = {\n accessAttempt,\n expectedLocalCursor: null,\n preparedDeniedProjection: !accessAttempt.startedDenied,\n projection: await loadProjection(input),\n requestCursor: undefined,\n retriedBindingFailure: false,\n retriedInvalidCursor: false,\n staleRetries: 0,\n };\n resetRequestCursor(state);\n\n for (let page = 0; page < MAX_READ_MODEL_PAGES; page += 1) {\n const request = await requestReadModelPage(input, state);\n if (request.kind === \"done\") {\n return request.value;\n }\n if (request.kind === \"continue\") {\n continue;\n }\n const applied = await applyReadModelPage(input, state, request.response);\n if (applied.kind === \"done\") {\n return applied.value;\n }\n }\n\n input.logError?.(\n \"Organization read-model reconciliation exceeded page limit\",\n );\n const retained = localResult(input, state, { failed: true });\n return retained.kind === \"done\" ? retained.value : null;\n}\n"]}
|
|
@@ -4,7 +4,7 @@ import { deleteDocumentPlacementRowsByContainerIds, deleteDocumentPlacementRowsB
|
|
|
4
4
|
import { clearDocumentDiscoveryEvidenceOnRemoteReset } from "../../data/persistence/documents/documentDiscoveryReset.js";
|
|
5
5
|
import { documentIntentLinkTargets } from "../../data/sqlite/documentPlacementIntentSchema.js";
|
|
6
6
|
import { organizationDataUsageCategories, organizationDataUsageSnapshots, } from "../../data/sqlite/organizationDataUsageSchema.js";
|
|
7
|
-
import { organizationPresentationDenials, organizationReadModelContainerGrants, organizationReadModelDirectoryUsers, organizationReadModelGroupMembers,
|
|
7
|
+
import { organizationPresentationDenials, organizationReadModelContainerGrants, organizationReadModelDirectoryUsers, organizationReadModelGroupMembers, organizationReadModelGroups, organizationReadModelRequesters, organizationReadModelState, } from "../../data/sqlite/organizationReadModelSchema.js";
|
|
8
8
|
import { clientSqlTables, containerCreateIntents, containerHydrationTombstones, containerMoveIntents, containers, documentAttachmentBlobProjection, documentMoveIntents, documentPendingAttachments, documentPendingUpdates, documentProjection, documentSyncFailures, documents, dormantContainerMetadata, dormantMetadataSweepRequests, } from "../../data/sqlite/schema.js";
|
|
9
9
|
import { getClientSQLitePersistenceRuntime, } from "../../data/sqlite/sqlitePersistenceRuntime.js";
|
|
10
10
|
import { ensureSqlTables } from "../../data/sqlite/sqlTableSchema.js";
|
|
@@ -22,10 +22,8 @@ async function clearOrganizationPresentationRows(tx, organizationId) {
|
|
|
22
22
|
organizationDataUsageSnapshots,
|
|
23
23
|
organizationReadModelContainerGrants,
|
|
24
24
|
organizationReadModelGroupMembers,
|
|
25
|
-
organizationReadModelGroupMemberships,
|
|
26
25
|
organizationReadModelDirectoryUsers,
|
|
27
26
|
organizationReadModelGroups,
|
|
28
|
-
organizationReadModelPolicyHeads,
|
|
29
27
|
organizationReadModelRequesters,
|
|
30
28
|
organizationReadModelState,
|
|
31
29
|
organizationPresentationDenials,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remoteReset.js","sourceRoot":"","sources":["remoteReset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,8CAA8C,EAAE,MAAM,uEAAuE,CAAC;AACvI,OAAO,EACL,yCAAyC,EACzC,wCAAwC,GACzC,MAAM,0EAA0E,CAAC;AAClF,OAAO,EAAE,2CAA2C,EAAE,MAAM,yDAAyD,CAAC;AACtH,OAAO,EAAE,yBAAyB,EAAE,MAAM,iDAAiD,CAAC;AAC5F,OAAO,EACL,+BAA+B,EAC/B,8BAA8B,GAC/B,MAAM,+CAA+C,CAAC;AACvD,OAAO,EACL,+BAA+B,EAC/B,oCAAoC,EACpC,mCAAmC,EACnC,iCAAiC,EACjC,qCAAqC,EACrC,2BAA2B,EAC3B,gCAAgC,EAChC,+BAA+B,EAC/B,0BAA0B,GAC3B,MAAM,+CAA+C,CAAC;AACvD,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,4BAA4B,EAC5B,oBAAoB,EACpB,UAAU,EACV,gCAAgC,EAChC,mBAAmB,EACnB,0BAA0B,EAC1B,sBAAsB,EACtB,kBAAkB,EAClB,oBAAoB,EACpB,SAAS,EACT,wBAAwB,EACxB,4BAA4B,GAC7B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAEL,iCAAiC,GAClC,MAAM,4CAA4C,CAAC;AAEpD,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,EAAE,gCAAgC,EAAE,MAAM,sDAAsD,CAAC;AACxG,OAAO,EAAE,4BAA4B,EAAE,MAAM,0BAA0B,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EACL,eAAe,GAGhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAGL,2BAA2B,GAC5B,MAAM,oBAAoB,CAAC;AAO5B,MAAM,4BAA4B,GAAG,kBAAkB,CAAC;AAexD,KAAK,UAAU,iCAAiC,CAC9C,EAAgC,EAChC,cAAsB;IAEtB,KAAK,MAAM,KAAK,IAAI;QAClB,+BAA+B;QAC/B,8BAA8B;QAC9B,oCAAoC;QACpC,iCAAiC;QACjC,qCAAqC;QACrC,mCAAmC;QACnC,2BAA2B;QAC3B,gCAAgC;QAChC,+BAA+B;QAC/B,0BAA0B;QAC1B,+BAA+B;KACvB,EAAE,CAAC;QACX,MAAM,EAAE;aACL,MAAM,CAAC,KAAK,CAAC;aACb,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;aAC/C,GAAG,EAAE,CAAC;IACX,CAAC;AACH,CAAC;AASD,KAAK,UAAU,wBAAwB,CACrC,KAA4B;IAE5B,KAAK,MAAM,cAAc,IAAI,kBAAkB,CAC7C,KAAK,CAAC,QAAQ,CAAC,YAAY,CAC5B,EAAE,CAAC;QACF,MAAM,yCAAyC,CAAC,KAAK,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC;QAC1E,MAAM,KAAK,CAAC,EAAE;aACX,MAAM,CAAC,oBAAoB,CAAC;aAC5B,KAAK,CAAC,OAAO,CAAC,oBAAoB,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;aAChE,GAAG,EAAE,CAAC;QACT,MAAM,KAAK,CAAC,EAAE;aACX,MAAM,CAAC,sBAAsB,CAAC;aAC9B,KAAK,CAAC,OAAO,CAAC,sBAAsB,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;aAClE,GAAG,EAAE,CAAC;QACT,MAAM,KAAK,CAAC,EAAE;aACX,MAAM,CAAC,4BAA4B,CAAC;aACpC,KAAK,CAAC,OAAO,CAAC,4BAA4B,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;aACxE,GAAG,EAAE,CAAC;IACX,CAAC;AACH,CAAC;AAED,KAAK,UAAU,uBAAuB,CACpC,KAA4B;IAE5B,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,GAAG,KAAK,CAAC;IAC/B,KAAK,MAAM,eAAe,IAAI,kBAAkB,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;QAC1E,MAAM,wCAAwC,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC;IACtE,CAAC;IACD,MAAM,4BAA4B,CAAC;QACjC,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;QAC1C,gBAAgB,EAAE,QAAQ,CAAC,gBAAgB;QAC3C,EAAE;KACH,CAAC,CAAC;IACH,KAAK,MAAM,YAAY,IAAI,kBAAkB,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACzE,MAAM,EAAE;aACL,MAAM,CAAC,yBAAyB,CAAC;aACjC,KAAK,CACJ,OAAO,CACL,yBAAyB,CAAC,QAAQ,EAClC,EAAE;aACC,MAAM,CAAC,EAAE,EAAE,EAAE,mBAAmB,CAAC,EAAE,EAAE,CAAC;aACtC,IAAI,CAAC,mBAAmB,CAAC;aACzB,KAAK,CAAC,OAAO,CAAC,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAC7D,CACF;aACA,GAAG,EAAE,CAAC;QACT,MAAM,EAAE;aACL,MAAM,CAAC,mBAAmB,CAAC;aAC3B,KAAK,CAAC,OAAO,CAAC,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;aACzD,GAAG,EAAE,CAAC;IACX,CAAC;IACD,KAAK,MAAM,aAAa,IAAI,kBAAkB,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QACtE,MAAM,EAAE;aACL,MAAM,CAAC,sBAAsB,CAAC;aAC9B,KAAK,CACJ,EAAE,CACA,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAC3B,GAAG,CACD,EAAE,CAAC,sBAAsB,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,EAC/C,EAAE,CAAC,sBAAsB,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAChD,CACF,CACF,CACF;aACA,GAAG,EAAE,CAAC;QACT,MAAM,EAAE;aACL,MAAM,CAAC,oBAAoB,CAAC;aAC5B,KAAK,CACJ,EAAE,CACA,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAC3B,GAAG,CACD,EAAE,CAAC,oBAAoB,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,EAC7C,EAAE,CAAC,oBAAoB,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAC9C,CACF,CACF,CACF;aACA,GAAG,EAAE,CAAC;IACX,CAAC;AACH,CAAC;AAED,KAAK,UAAU,qBAAqB,CAClC,KAA4B;IAE5B,MAAM,EAAE,cAAc,EAAE,EAAE,EAAE,GAAG,KAAK,CAAC;IACrC,MAAM,iCAAiC,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC;IAC5D,KAAK,MAAM,KAAK,IAAI;QAClB,wBAAwB;QACxB,4BAA4B;KACpB,EAAE,CAAC;QACX,MAAM,EAAE;aACL,MAAM,CAAC,KAAK,CAAC;aACb,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;aAC/C,GAAG,EAAE,CAAC;IACX,CAAC;IACD,MAAM,2CAA2C,CAAC,EAAE,EAAE;QACpD,YAAY,EAAE,KAAK,CAAC,QAAQ,CAAC,YAAY;QACzC,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,cAAc;KAC3C,CAAC,CAAC;IACH,MAAM,6BAA6B,CAAC,KAAK,CAAC,CAAC;IAC3C,MAAM,wBAAwB,CAAC,KAAK,CAAC,CAAC;IACtC,MAAM,uBAAuB,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,2BAA2B,CAAC;QAChC,YAAY,EAAE,KAAK,CAAC,QAAQ,CAAC,YAAY;QACzC,EAAE;KACH,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAC,KAKjC;IACC,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,GAAG,KAAK,CAAC;IAC3C,KAAK,MAAM,GAAG,IAAI,QAAQ,CAAC,YAAY,EAAE,CAAC;QACxC,MAAM,EAAE;aACL,MAAM,CAAC,SAAS,CAAC;aACjB,GAAG,CAAC;YACH,WAAW,EAAE,CAAC;YACd,eAAe,EAAE,IAAI;YACrB,gBAAgB,EAAE,IAAI;YACtB,UAAU,EAAE,IAAI;YAChB,kBAAkB,EAAE,IAAI;YACxB,sBAAsB,EAAE,IAAI;YAC5B,aAAa,EAAE,IAAI;YACnB,gBAAgB,EAAE,IAAI;YACtB,kBAAkB,EAAE,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,kBAAkB;YAC5D,SAAS,EAAE,GAAG;SACf,CAAC;aACD,KAAK,CACJ,GAAG,CACD,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,EAClC,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CACnC,CACF;aACA,GAAG,EAAE,CAAC;IACX,CAAC;IACD,KAAK,MAAM,YAAY,IAAI,kBAAkB,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACzE,MAAM,EAAE;aACL,MAAM,CAAC,kBAAkB,CAAC;aAC1B,GAAG,CAAC;YACH,UAAU,EAAE,IAAI;YAChB,cAAc,EACZ,KAAK,CAAC,WAAW,EAAE,cAAc,IAAI,KAAK,CAAC,cAAc;SAC5D,CAAC;aACD,KAAK,CAAC,OAAO,CAAC,kBAAkB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;aACxD,GAAG,EAAE,CAAC;IACX,CAAC;IACD,wEAAwE;IACxE,4CAA4C;IAC5C,KAAK,MAAM,YAAY,IAAI,KAAK,CAAC,WAAW;QAC1C,CAAC,CAAC,kBAAkB,CAAC,QAAQ,CAAC,YAAY,CAAC;QAC3C,CAAC,CAAC,EAAE,EAAE,CAAC;QACP,MAAM,8CAA8C,CAAC,EAAE,EAAE;YACvD,YAAY;YACZ,cAAc,EAAE,KAAK,CAAC,cAAc;YACpC,YAAY,EAAE,GAAG;SAClB,CAAC,CAAC;IACL,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,QAAQ,CAAC,aAAa,EAAE,CAAC;QACzC,MAAM,EAAE;aACL,MAAM,CAAC,UAAU,CAAC;aAClB,GAAG,CAAC;YACH,kBAAkB,EAAE,IAAI;YACxB,cAAc,EACZ,KAAK,CAAC,WAAW,EAAE,cAAc,IAAI,KAAK,CAAC,cAAc;YAC3D,QAAQ,EACN,KAAK,CAAC,WAAW,IAAI,GAAG,CAAC,QAAQ,KAAK,IAAI;gBACxC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,eAAe;gBACnC,CAAC,CAAC,GAAG,CAAC,QAAQ;YAClB,eAAe,EAAE,IAAI;YACrB,eAAe,EAAE,IAAI;YACrB,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAClD,cAAc,EAAE,GAAG;SACpB,CAAC;aACD,KAAK,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;aAChC,GAAG,EAAE,CAAC;IACX,CAAC;AACH,CAAC;AAED,KAAK,UAAU,yBAAyB,CAAC,KAIxC;IACC,KAAK,MAAM,WAAW,IAAI,kBAAkB,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,CAAC;QACpE,MAAM,KAAK,CAAC,EAAE;aACX,MAAM,CAAC,sBAAsB,CAAC;aAC9B,MAAM,CACL,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YAC3B,GAAG,MAAM;YACT,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;YACvB,SAAS,EAAE,KAAK,CAAC,GAAG;SACrB,CAAC,CAAC,CACJ;aACA,GAAG,EAAE,CAAC;IACX,CAAC;AACH,CAAC;AAED,KAAK,UAAU,0BAA0B,CAAC,KAKzC;IACC,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QACxD,MAAM,QAAQ,GACZ,GAAG,CAAC,QAAQ,IAAI,KAAK,CAAC,KAAK,CAAC,WAAW,EAAE,eAAe,IAAI,IAAI,CAAC;QACnE,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACpD,CAAC,CAAC,CAAC;IACH,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAChC,KAAK,MAAM,QAAQ,IAAI,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,MAAM,KAAK,CAAC,EAAE;aACX,MAAM,CAAC,sBAAsB,CAAC;aAC9B,MAAM,CACL,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACrB,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;YACvB,WAAW,EAAE,GAAG,CAAC,EAAE;YACnB,iBAAiB,EAAE,GAAG,CAAC,QAAQ;YAC/B,UAAU,EAAE,4BAA4B;YACxC,UAAU,EAAE,SAAkB;YAC9B,iBAAiB,EAAE,IAAI;YACvB,6BAA6B,EAAE,IAAI;YACnC,wBAAwB,EAAE,IAAI;YAC9B,SAAS,EAAE,IAAI;YACf,SAAS,EAAE,KAAK,CAAC,GAAG;YACpB,SAAS,EAAE,KAAK,CAAC,GAAG;SACrB,CAAC,CAAC,CACJ;aACA,GAAG,EAAE,CAAC;IACX,CAAC;IACD,OAAO,IAAI,CAAC,MAAM,CAAC;AACrB,CAAC;AAED,KAAK,UAAU,2BAA2B,CAAC,KAI1C;IACC,KAAK,MAAM,eAAe,IAAI,kBAAkB,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAC1E,MAAM,KAAK,CAAC,EAAE;aACX,MAAM,CAAC,0BAA0B,CAAC;aAClC,MAAM,CACL,eAAe,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;YACnC,GAAG,UAAU;YACb,SAAS,EAAE,KAAK,CAAC,GAAG;SACrB,CAAC,CAAC,CACJ;aACA,GAAG,EAAE,CAAC;QACT,MAAM,KAAK,CAAC,EAAE;aACX,MAAM,CAAC,gCAAgC,CAAC;aACxC,KAAK,CACJ,EAAE,CACA,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CACpC,GAAG,CACD,EAAE,CAAC,gCAAgC,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,CAAC,EAChE,EAAE,CAAC,gCAAgC,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,CAC/D,CACF,CACF,CACF;aACA,GAAG,EAAE,CAAC;IACX,CAAC;AACH,CAAC;AAED,KAAK,UAAU,iCAAiC,CAAC,KAKhD;IACC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IAC3B,MAAM,qBAAqB,CAAC;QAC1B,iBAAiB,EAAE,KAAK,CAAC,KAAK,CAAC,iBAAiB;QAChD,cAAc,EAAE,KAAK,CAAC,KAAK,CAAC,cAAc;QAC1C,QAAQ;QACR,EAAE,EAAE,KAAK,CAAC,EAAE;KACb,CAAC,CAAC;IACH,MAAM,kBAAkB,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;IAC9E,MAAM,yBAAyB,CAAC;QAC9B,eAAe,EAAE,KAAK,CAAC,KAAK,CAAC,eAAe;QAC5C,GAAG;QACH,EAAE,EAAE,KAAK,CAAC,EAAE;KACb,CAAC,CAAC;IACH,MAAM,0BAA0B,GAAG,MAAM,0BAA0B,CAAC;QAClE,GAAG;QACH,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,QAAQ;QACR,EAAE,EAAE,KAAK,CAAC,EAAE;KACb,CAAC,CAAC;IACH,MAAM,2BAA2B,CAAC;QAChC,iBAAiB,EAAE,KAAK,CAAC,KAAK,CAAC,iBAAiB;QAChD,GAAG;QACH,EAAE,EAAE,KAAK,CAAC,EAAE;KACb,CAAC,CAAC;IACH,OAAO;QACL,iCAAiC,EAC/B,QAAQ,CAAC,iCAAiC;QAC5C,+BAA+B,EAAE,QAAQ,CAAC,+BAA+B;QACzE,8BAA8B,EAAE,QAAQ,CAAC,8BAA8B;QACvE,2BAA2B,EAAE,QAAQ,CAAC,2BAA2B;QACjE,sBAAsB,EAAE,QAAQ,CAAC,sBAAsB;QACvD,2BAA2B,EAAE,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC,MAAM;QACjE,0BAA0B;QAC1B,yBAAyB,EAAE,KAAK,CAAC,KAAK,CAAC,eAAe,CAAC,MAAM;QAC7D,mBAAmB,EAAE,QAAQ,CAAC,aAAa,CAAC,MAAM;QAClD,kBAAkB,EAAE,QAAQ,CAAC,YAAY,CAAC,MAAM;KACjD,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAAgB,EAChB,KAAuB,EACvB,SAAuC;IAEvC,OAAO,gCAAgC,CACrC,OAAO,EACP,KAAK,CAAC,cAAc,EACpB,KAAK,IAAI,EAAE;QACT,MAAM,eAAe,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,iCAAiC,CAAC,OAAO,CAAC,CAAC;QAC3D,MAAM,kBAAkB,GAAG,KAAK,EAAE,EAAgC,EAAE,EAAE;YACpE,IAAI,SAAS,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;gBAC9B,MAAM,IAAI,KAAK,CACb,qDAAqD,CACtD,CAAC;YACJ,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,2BAA2B,CAChD,EAAE,EACF,KAAK,CAAC,cAAc,CACrB,CAAC;YACF,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,EAAE,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;YAC/D,OAAO,iCAAiC,CAAC;gBACvC,KAAK;gBACL,KAAK;gBACL,QAAQ;gBACR,EAAE;aACH,CAAC,CAAC;QACL,CAAC,CAAC;QACF,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,OAAO,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC;QACjD,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,kBAAkB,CAC9C,kBAAkB,EAClB,SAAS,CACV,CAAC;QACF,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACzE,CAAC;QACD,OAAO,OAAO,CAAC,MAAM,CAAC;IACxB,CAAC,CACF,CAAC;AACJ,CAAC","sourcesContent":["import { and, eq, inArray, or } from \"drizzle-orm\";\nimport { recordSupersededContainerBindingsInTransaction } from \"../../data/persistence/container-contents/supersededContainerBindings\";\nimport {\n deleteDocumentPlacementRowsByContainerIds,\n deleteDocumentPlacementRowsByDocumentIds,\n} from \"../../data/persistence/containers/documentContainerProjectionPersistence\";\nimport { clearDocumentDiscoveryEvidenceOnRemoteReset } from \"../../data/persistence/documents/documentDiscoveryReset\";\nimport { documentIntentLinkTargets } from \"../../data/sqlite/documentPlacementIntentSchema\";\nimport {\n organizationDataUsageCategories,\n organizationDataUsageSnapshots,\n} from \"../../data/sqlite/organizationDataUsageSchema\";\nimport {\n organizationPresentationDenials,\n organizationReadModelContainerGrants,\n organizationReadModelDirectoryUsers,\n organizationReadModelGroupMembers,\n organizationReadModelGroupMemberships,\n organizationReadModelGroups,\n organizationReadModelPolicyHeads,\n organizationReadModelRequesters,\n organizationReadModelState,\n} from \"../../data/sqlite/organizationReadModelSchema\";\nimport {\n clientSqlTables,\n containerCreateIntents,\n containerHydrationTombstones,\n containerMoveIntents,\n containers,\n documentAttachmentBlobProjection,\n documentMoveIntents,\n documentPendingAttachments,\n documentPendingUpdates,\n documentProjection,\n documentSyncFailures,\n documents,\n dormantContainerMetadata,\n dormantMetadataSweepRequests,\n} from \"../../data/sqlite/schema\";\nimport {\n type ClientSQLiteTransactionScope,\n getClientSQLitePersistenceRuntime,\n} from \"../../data/sqlite/sqlitePersistenceRuntime\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport { ensureSqlTables } from \"../../data/sqlite/sqlTableSchema\";\nimport { runOrganizationPresentationReset } from \"../organizations/organizationPresentationAccessState\";\nimport { clearResetPendingAttachments } from \"./remoteResetAttachments\";\nimport { remoteResetBatches } from \"./remoteResetBatches\";\nimport { clearRemoteResetSyncCursors } from \"./remoteResetCursorScope\";\nimport {\n buildResetPlans,\n type ResetAttachmentUpload,\n type ResetDocumentUpdate,\n} from \"./remoteResetPlans\";\nimport { clearRemoteResetPrincipalRows } from \"./remoteResetPrincipalScope\";\nimport {\n type RemoteResetInput,\n type RemoteSyncStateSnapshot,\n readRemoteSyncStateSnapshot,\n} from \"./remoteResetScope\";\n\nexport type {\n RemoteResetInput,\n RemoteResetReplacement,\n} from \"./remoteResetScope\";\n\nconst CONTAINER_CREATE_INTENT_TYPE = \"container.create\";\n\nexport interface ClearRemoteSyncStateResult {\n readonly clearedContainerCreateIntentCount: number;\n readonly clearedContainerMoveIntentCount: number;\n readonly clearedDocumentMoveIntentCount: number;\n readonly clearedPrincipalPolicyCount: number;\n readonly clearedSyncCursorCount: number;\n readonly queuedAttachmentUploadCount: number;\n readonly queuedContainerCreateCount: number;\n readonly queuedDocumentUpdateCount: number;\n readonly resetContainerCount: number;\n readonly resetDocumentCount: number;\n}\n\nasync function clearOrganizationPresentationRows(\n tx: ClientSQLiteTransactionScope,\n organizationId: string,\n): Promise<void> {\n for (const table of [\n organizationDataUsageCategories,\n organizationDataUsageSnapshots,\n organizationReadModelContainerGrants,\n organizationReadModelGroupMembers,\n organizationReadModelGroupMemberships,\n organizationReadModelDirectoryUsers,\n organizationReadModelGroups,\n organizationReadModelPolicyHeads,\n organizationReadModelRequesters,\n organizationReadModelState,\n organizationPresentationDenials,\n ] as const) {\n await tx\n .delete(table)\n .where(eq(table.organizationId, organizationId))\n .run();\n }\n}\n\ninterface ScopedRemoteRowsInput {\n attachmentUploads: readonly ResetAttachmentUpload[];\n organizationId: string;\n snapshot: RemoteSyncStateSnapshot;\n tx: ClientSQLiteTransactionScope;\n}\n\nasync function clearScopedContainerRows(\n input: ScopedRemoteRowsInput,\n): Promise<void> {\n for (const containerBatch of remoteResetBatches(\n input.snapshot.containerIds,\n )) {\n await deleteDocumentPlacementRowsByContainerIds(input.tx, containerBatch);\n await input.tx\n .delete(containerMoveIntents)\n .where(inArray(containerMoveIntents.containerId, containerBatch))\n .run();\n await input.tx\n .delete(containerCreateIntents)\n .where(inArray(containerCreateIntents.containerId, containerBatch))\n .run();\n await input.tx\n .delete(containerHydrationTombstones)\n .where(inArray(containerHydrationTombstones.containerId, containerBatch))\n .run();\n }\n}\n\nasync function clearScopedDocumentRows(\n input: ScopedRemoteRowsInput,\n): Promise<void> {\n const { snapshot, tx } = input;\n for (const documentIdBatch of remoteResetBatches(snapshot.oldDocumentIds)) {\n await deleteDocumentPlacementRowsByDocumentIds(tx, documentIdBatch);\n }\n await clearResetPendingAttachments({\n attachmentUploads: input.attachmentUploads,\n documentLocalIds: snapshot.documentLocalIds,\n tx,\n });\n for (const localIdBatch of remoteResetBatches(snapshot.documentLocalIds)) {\n await tx\n .delete(documentIntentLinkTargets)\n .where(\n inArray(\n documentIntentLinkTargets.intentId,\n tx\n .select({ id: documentMoveIntents.id })\n .from(documentMoveIntents)\n .where(inArray(documentMoveIntents.localId, localIdBatch)),\n ),\n )\n .run();\n await tx\n .delete(documentMoveIntents)\n .where(inArray(documentMoveIntents.localId, localIdBatch))\n .run();\n }\n for (const documentBatch of remoteResetBatches(snapshot.documentRows)) {\n await tx\n .delete(documentPendingUpdates)\n .where(\n or(\n ...documentBatch.map((row) =>\n and(\n eq(documentPendingUpdates.appKind, row.appKind),\n eq(documentPendingUpdates.localId, row.localId),\n ),\n ),\n ),\n )\n .run();\n await tx\n .delete(documentSyncFailures)\n .where(\n or(\n ...documentBatch.map((row) =>\n and(\n eq(documentSyncFailures.appKind, row.appKind),\n eq(documentSyncFailures.localId, row.localId),\n ),\n ),\n ),\n )\n .run();\n }\n}\n\nasync function clearScopedRemoteRows(\n input: ScopedRemoteRowsInput,\n): Promise<void> {\n const { organizationId, tx } = input;\n await clearOrganizationPresentationRows(tx, organizationId);\n for (const table of [\n dormantContainerMetadata,\n dormantMetadataSweepRequests,\n ] as const) {\n await tx\n .delete(table)\n .where(eq(table.organizationId, organizationId))\n .run();\n }\n await clearDocumentDiscoveryEvidenceOnRemoteReset(tx, {\n containerIds: input.snapshot.containerIds,\n documentIds: input.snapshot.oldDocumentIds,\n });\n await clearRemoteResetPrincipalRows(input);\n await clearScopedContainerRows(input);\n await clearScopedDocumentRows(input);\n await clearRemoteResetSyncCursors({\n containerIds: input.snapshot.containerIds,\n tx,\n });\n}\n\nasync function resetRemoteColumns(input: {\n now: string;\n reset: RemoteResetInput;\n snapshot: RemoteSyncStateSnapshot;\n tx: ClientSQLiteTransactionScope;\n}): Promise<void> {\n const { now, reset, snapshot, tx } = input;\n for (const row of snapshot.documentRows) {\n await tx\n .update(documents)\n .set({\n accessEpoch: 1,\n accessStateHash: null,\n contentKeyBundle: null,\n documentId: null,\n documentKekTargets: null,\n documentManifestBundle: null,\n lastCommitLsn: null,\n pullContinuation: null,\n recoveryDocumentId: row.documentId ?? row.recoveryDocumentId,\n updatedAt: now,\n })\n .where(\n and(\n eq(documents.appKind, row.appKind),\n eq(documents.localId, row.localId),\n ),\n )\n .run();\n }\n for (const localIdBatch of remoteResetBatches(snapshot.documentLocalIds)) {\n await tx\n .update(documentProjection)\n .set({\n documentId: null,\n organizationId:\n reset.replacement?.organizationId ?? reset.organizationId,\n })\n .where(inArray(documentProjection.localId, localIdBatch))\n .run();\n }\n // Replacement re-homes folders under their ids; the purged organization\n // can never bind them again on this device.\n for (const containerIds of reset.replacement\n ? remoteResetBatches(snapshot.containerIds)\n : []) {\n await recordSupersededContainerBindingsInTransaction(tx, {\n containerIds,\n organizationId: reset.organizationId,\n supersededAt: now,\n });\n }\n for (const row of snapshot.containerRows) {\n await tx\n .update(containers)\n .set({\n metadataDocumentId: null,\n organizationId:\n reset.replacement?.organizationId ?? reset.organizationId,\n parentId:\n reset.replacement && row.parentId === null\n ? reset.replacement.rootContainerId\n : row.parentId,\n serverCreatedAt: null,\n serverUpdatedAt: null,\n ...(reset.replacement ? { systemSlot: null } : {}),\n localUpdatedAt: now,\n })\n .where(eq(containers.id, row.id))\n .run();\n }\n}\n\nasync function queueResetDocumentUpdates(input: {\n documentUpdates: readonly ResetDocumentUpdate[];\n now: string;\n tx: ClientSQLiteTransactionScope;\n}): Promise<void> {\n for (const updateBatch of remoteResetBatches(input.documentUpdates)) {\n await input.tx\n .insert(documentPendingUpdates)\n .values(\n updateBatch.map((update) => ({\n ...update,\n id: crypto.randomUUID(),\n createdAt: input.now,\n })),\n )\n .run();\n }\n}\n\nasync function queueResetContainerCreates(input: {\n now: string;\n reset: RemoteResetInput;\n snapshot: RemoteSyncStateSnapshot;\n tx: ClientSQLiteTransactionScope;\n}): Promise<number> {\n const rows = input.snapshot.containerRows.flatMap((row) => {\n const parentId =\n row.parentId ?? input.reset.replacement?.rootContainerId ?? null;\n return parentId ? [{ id: row.id, parentId }] : [];\n });\n if (rows.length === 0) return 0;\n for (const rowBatch of remoteResetBatches(rows)) {\n await input.tx\n .insert(containerCreateIntents)\n .values(\n rowBatch.map((row) => ({\n id: crypto.randomUUID(),\n containerId: row.id,\n parentContainerId: row.parentId,\n intentType: CONTAINER_CREATE_INTENT_TYPE,\n syncStatus: \"pending\" as const,\n remoteContainerId: null,\n remoteMetadataAccessStateHash: null,\n remoteMetadataDocumentId: null,\n lastError: null,\n createdAt: input.now,\n updatedAt: input.now,\n })),\n )\n .run();\n }\n return rows.length;\n}\n\nasync function queueResetAttachmentUploads(input: {\n attachmentUploads: readonly ResetAttachmentUpload[];\n now: string;\n tx: ClientSQLiteTransactionScope;\n}): Promise<void> {\n for (const attachmentBatch of remoteResetBatches(input.attachmentUploads)) {\n await input.tx\n .insert(documentPendingAttachments)\n .values(\n attachmentBatch.map((attachment) => ({\n ...attachment,\n createdAt: input.now,\n })),\n )\n .run();\n await input.tx\n .delete(documentAttachmentBlobProjection)\n .where(\n or(\n ...attachmentBatch.map((attachment) =>\n and(\n eq(documentAttachmentBlobProjection.localId, attachment.localId),\n eq(documentAttachmentBlobProjection.slotId, attachment.slotId),\n ),\n ),\n ),\n )\n .run();\n }\n}\n\nasync function clearRemoteSyncStateInTransaction(input: {\n plans: Awaited<ReturnType<typeof buildResetPlans>>;\n reset: RemoteResetInput;\n snapshot: RemoteSyncStateSnapshot;\n tx: ClientSQLiteTransactionScope;\n}): Promise<ClearRemoteSyncStateResult> {\n const now = new Date().toISOString();\n const { snapshot } = input;\n await clearScopedRemoteRows({\n attachmentUploads: input.plans.attachmentUploads,\n organizationId: input.reset.organizationId,\n snapshot,\n tx: input.tx,\n });\n await resetRemoteColumns({ now, reset: input.reset, snapshot, tx: input.tx });\n await queueResetDocumentUpdates({\n documentUpdates: input.plans.documentUpdates,\n now,\n tx: input.tx,\n });\n const queuedContainerCreateCount = await queueResetContainerCreates({\n now,\n reset: input.reset,\n snapshot,\n tx: input.tx,\n });\n await queueResetAttachmentUploads({\n attachmentUploads: input.plans.attachmentUploads,\n now,\n tx: input.tx,\n });\n return {\n clearedContainerCreateIntentCount:\n snapshot.clearedContainerCreateIntentCount,\n clearedContainerMoveIntentCount: snapshot.clearedContainerMoveIntentCount,\n clearedDocumentMoveIntentCount: snapshot.clearedDocumentMoveIntentCount,\n clearedPrincipalPolicyCount: snapshot.clearedPrincipalPolicyCount,\n clearedSyncCursorCount: snapshot.clearedSyncCursorCount,\n queuedAttachmentUploadCount: input.plans.attachmentUploads.length,\n queuedContainerCreateCount,\n queuedDocumentUpdateCount: input.plans.documentUpdates.length,\n resetContainerCount: snapshot.containerRows.length,\n resetDocumentCount: snapshot.documentRows.length,\n };\n}\n\nexport async function clearRemoteSyncState(\n execSql: ExecSql,\n reset: RemoteResetInput,\n canCommit?: (() => boolean) | undefined,\n): Promise<ClearRemoteSyncStateResult> {\n return runOrganizationPresentationReset(\n execSql,\n reset.organizationId,\n async () => {\n await ensureSqlTables(execSql, clientSqlTables);\n const runtime = getClientSQLitePersistenceRuntime(execSql);\n const resetInTransaction = async (tx: ClientSQLiteTransactionScope) => {\n if (canCommit && !canCommit()) {\n throw new Error(\n \"Remote sync reset aborted: session identity changed\",\n );\n }\n const snapshot = await readRemoteSyncStateSnapshot(\n tx,\n reset.organizationId,\n );\n const plans = await buildResetPlans(tx, snapshot.documentRows);\n return clearRemoteSyncStateInTransaction({\n plans,\n reset,\n snapshot,\n tx,\n });\n };\n if (!canCommit) {\n return runtime.transaction(resetInTransaction);\n }\n const outcome = await runtime.guardedTransaction(\n resetInTransaction,\n canCommit,\n );\n if (!outcome.committed || !outcome.result) {\n throw new Error(\"Remote sync reset aborted: session identity changed\");\n }\n return outcome.result;\n },\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"remoteReset.js","sourceRoot":"","sources":["remoteReset.ts"],"names":[],"mappings":"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","sourcesContent":["import { and, eq, inArray, or } from \"drizzle-orm\";\nimport { recordSupersededContainerBindingsInTransaction } from \"../../data/persistence/container-contents/supersededContainerBindings\";\nimport {\n deleteDocumentPlacementRowsByContainerIds,\n deleteDocumentPlacementRowsByDocumentIds,\n} from \"../../data/persistence/containers/documentContainerProjectionPersistence\";\nimport { clearDocumentDiscoveryEvidenceOnRemoteReset } from \"../../data/persistence/documents/documentDiscoveryReset\";\nimport { documentIntentLinkTargets } from \"../../data/sqlite/documentPlacementIntentSchema\";\nimport {\n organizationDataUsageCategories,\n organizationDataUsageSnapshots,\n} from \"../../data/sqlite/organizationDataUsageSchema\";\nimport {\n organizationPresentationDenials,\n organizationReadModelContainerGrants,\n organizationReadModelDirectoryUsers,\n organizationReadModelGroupMembers,\n organizationReadModelGroups,\n organizationReadModelRequesters,\n organizationReadModelState,\n} from \"../../data/sqlite/organizationReadModelSchema\";\nimport {\n clientSqlTables,\n containerCreateIntents,\n containerHydrationTombstones,\n containerMoveIntents,\n containers,\n documentAttachmentBlobProjection,\n documentMoveIntents,\n documentPendingAttachments,\n documentPendingUpdates,\n documentProjection,\n documentSyncFailures,\n documents,\n dormantContainerMetadata,\n dormantMetadataSweepRequests,\n} from \"../../data/sqlite/schema\";\nimport {\n type ClientSQLiteTransactionScope,\n getClientSQLitePersistenceRuntime,\n} from \"../../data/sqlite/sqlitePersistenceRuntime\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport { ensureSqlTables } from \"../../data/sqlite/sqlTableSchema\";\nimport { runOrganizationPresentationReset } from \"../organizations/organizationPresentationAccessState\";\nimport { clearResetPendingAttachments } from \"./remoteResetAttachments\";\nimport { remoteResetBatches } from \"./remoteResetBatches\";\nimport { clearRemoteResetSyncCursors } from \"./remoteResetCursorScope\";\nimport {\n buildResetPlans,\n type ResetAttachmentUpload,\n type ResetDocumentUpdate,\n} from \"./remoteResetPlans\";\nimport { clearRemoteResetPrincipalRows } from \"./remoteResetPrincipalScope\";\nimport {\n type RemoteResetInput,\n type RemoteSyncStateSnapshot,\n readRemoteSyncStateSnapshot,\n} from \"./remoteResetScope\";\n\nexport type {\n RemoteResetInput,\n RemoteResetReplacement,\n} from \"./remoteResetScope\";\n\nconst CONTAINER_CREATE_INTENT_TYPE = \"container.create\";\n\nexport interface ClearRemoteSyncStateResult {\n readonly clearedContainerCreateIntentCount: number;\n readonly clearedContainerMoveIntentCount: number;\n readonly clearedDocumentMoveIntentCount: number;\n readonly clearedPrincipalPolicyCount: number;\n readonly clearedSyncCursorCount: number;\n readonly queuedAttachmentUploadCount: number;\n readonly queuedContainerCreateCount: number;\n readonly queuedDocumentUpdateCount: number;\n readonly resetContainerCount: number;\n readonly resetDocumentCount: number;\n}\n\nasync function clearOrganizationPresentationRows(\n tx: ClientSQLiteTransactionScope,\n organizationId: string,\n): Promise<void> {\n for (const table of [\n organizationDataUsageCategories,\n organizationDataUsageSnapshots,\n organizationReadModelContainerGrants,\n organizationReadModelGroupMembers,\n organizationReadModelDirectoryUsers,\n organizationReadModelGroups,\n organizationReadModelRequesters,\n organizationReadModelState,\n organizationPresentationDenials,\n ] as const) {\n await tx\n .delete(table)\n .where(eq(table.organizationId, organizationId))\n .run();\n }\n}\n\ninterface ScopedRemoteRowsInput {\n attachmentUploads: readonly ResetAttachmentUpload[];\n organizationId: string;\n snapshot: RemoteSyncStateSnapshot;\n tx: ClientSQLiteTransactionScope;\n}\n\nasync function clearScopedContainerRows(\n input: ScopedRemoteRowsInput,\n): Promise<void> {\n for (const containerBatch of remoteResetBatches(\n input.snapshot.containerIds,\n )) {\n await deleteDocumentPlacementRowsByContainerIds(input.tx, containerBatch);\n await input.tx\n .delete(containerMoveIntents)\n .where(inArray(containerMoveIntents.containerId, containerBatch))\n .run();\n await input.tx\n .delete(containerCreateIntents)\n .where(inArray(containerCreateIntents.containerId, containerBatch))\n .run();\n await input.tx\n .delete(containerHydrationTombstones)\n .where(inArray(containerHydrationTombstones.containerId, containerBatch))\n .run();\n }\n}\n\nasync function clearScopedDocumentRows(\n input: ScopedRemoteRowsInput,\n): Promise<void> {\n const { snapshot, tx } = input;\n for (const documentIdBatch of remoteResetBatches(snapshot.oldDocumentIds)) {\n await deleteDocumentPlacementRowsByDocumentIds(tx, documentIdBatch);\n }\n await clearResetPendingAttachments({\n attachmentUploads: input.attachmentUploads,\n documentLocalIds: snapshot.documentLocalIds,\n tx,\n });\n for (const localIdBatch of remoteResetBatches(snapshot.documentLocalIds)) {\n await tx\n .delete(documentIntentLinkTargets)\n .where(\n inArray(\n documentIntentLinkTargets.intentId,\n tx\n .select({ id: documentMoveIntents.id })\n .from(documentMoveIntents)\n .where(inArray(documentMoveIntents.localId, localIdBatch)),\n ),\n )\n .run();\n await tx\n .delete(documentMoveIntents)\n .where(inArray(documentMoveIntents.localId, localIdBatch))\n .run();\n }\n for (const documentBatch of remoteResetBatches(snapshot.documentRows)) {\n await tx\n .delete(documentPendingUpdates)\n .where(\n or(\n ...documentBatch.map((row) =>\n and(\n eq(documentPendingUpdates.appKind, row.appKind),\n eq(documentPendingUpdates.localId, row.localId),\n ),\n ),\n ),\n )\n .run();\n await tx\n .delete(documentSyncFailures)\n .where(\n or(\n ...documentBatch.map((row) =>\n and(\n eq(documentSyncFailures.appKind, row.appKind),\n eq(documentSyncFailures.localId, row.localId),\n ),\n ),\n ),\n )\n .run();\n }\n}\n\nasync function clearScopedRemoteRows(\n input: ScopedRemoteRowsInput,\n): Promise<void> {\n const { organizationId, tx } = input;\n await clearOrganizationPresentationRows(tx, organizationId);\n for (const table of [\n dormantContainerMetadata,\n dormantMetadataSweepRequests,\n ] as const) {\n await tx\n .delete(table)\n .where(eq(table.organizationId, organizationId))\n .run();\n }\n await clearDocumentDiscoveryEvidenceOnRemoteReset(tx, {\n containerIds: input.snapshot.containerIds,\n documentIds: input.snapshot.oldDocumentIds,\n });\n await clearRemoteResetPrincipalRows(input);\n await clearScopedContainerRows(input);\n await clearScopedDocumentRows(input);\n await clearRemoteResetSyncCursors({\n containerIds: input.snapshot.containerIds,\n tx,\n });\n}\n\nasync function resetRemoteColumns(input: {\n now: string;\n reset: RemoteResetInput;\n snapshot: RemoteSyncStateSnapshot;\n tx: ClientSQLiteTransactionScope;\n}): Promise<void> {\n const { now, reset, snapshot, tx } = input;\n for (const row of snapshot.documentRows) {\n await tx\n .update(documents)\n .set({\n accessEpoch: 1,\n accessStateHash: null,\n contentKeyBundle: null,\n documentId: null,\n documentKekTargets: null,\n documentManifestBundle: null,\n lastCommitLsn: null,\n pullContinuation: null,\n recoveryDocumentId: row.documentId ?? row.recoveryDocumentId,\n updatedAt: now,\n })\n .where(\n and(\n eq(documents.appKind, row.appKind),\n eq(documents.localId, row.localId),\n ),\n )\n .run();\n }\n for (const localIdBatch of remoteResetBatches(snapshot.documentLocalIds)) {\n await tx\n .update(documentProjection)\n .set({\n documentId: null,\n organizationId:\n reset.replacement?.organizationId ?? reset.organizationId,\n })\n .where(inArray(documentProjection.localId, localIdBatch))\n .run();\n }\n // Replacement re-homes folders under their ids; the purged organization\n // can never bind them again on this device.\n for (const containerIds of reset.replacement\n ? remoteResetBatches(snapshot.containerIds)\n : []) {\n await recordSupersededContainerBindingsInTransaction(tx, {\n containerIds,\n organizationId: reset.organizationId,\n supersededAt: now,\n });\n }\n for (const row of snapshot.containerRows) {\n await tx\n .update(containers)\n .set({\n metadataDocumentId: null,\n organizationId:\n reset.replacement?.organizationId ?? reset.organizationId,\n parentId:\n reset.replacement && row.parentId === null\n ? reset.replacement.rootContainerId\n : row.parentId,\n serverCreatedAt: null,\n serverUpdatedAt: null,\n ...(reset.replacement ? { systemSlot: null } : {}),\n localUpdatedAt: now,\n })\n .where(eq(containers.id, row.id))\n .run();\n }\n}\n\nasync function queueResetDocumentUpdates(input: {\n documentUpdates: readonly ResetDocumentUpdate[];\n now: string;\n tx: ClientSQLiteTransactionScope;\n}): Promise<void> {\n for (const updateBatch of remoteResetBatches(input.documentUpdates)) {\n await input.tx\n .insert(documentPendingUpdates)\n .values(\n updateBatch.map((update) => ({\n ...update,\n id: crypto.randomUUID(),\n createdAt: input.now,\n })),\n )\n .run();\n }\n}\n\nasync function queueResetContainerCreates(input: {\n now: string;\n reset: RemoteResetInput;\n snapshot: RemoteSyncStateSnapshot;\n tx: ClientSQLiteTransactionScope;\n}): Promise<number> {\n const rows = input.snapshot.containerRows.flatMap((row) => {\n const parentId =\n row.parentId ?? input.reset.replacement?.rootContainerId ?? null;\n return parentId ? [{ id: row.id, parentId }] : [];\n });\n if (rows.length === 0) return 0;\n for (const rowBatch of remoteResetBatches(rows)) {\n await input.tx\n .insert(containerCreateIntents)\n .values(\n rowBatch.map((row) => ({\n id: crypto.randomUUID(),\n containerId: row.id,\n parentContainerId: row.parentId,\n intentType: CONTAINER_CREATE_INTENT_TYPE,\n syncStatus: \"pending\" as const,\n remoteContainerId: null,\n remoteMetadataAccessStateHash: null,\n remoteMetadataDocumentId: null,\n lastError: null,\n createdAt: input.now,\n updatedAt: input.now,\n })),\n )\n .run();\n }\n return rows.length;\n}\n\nasync function queueResetAttachmentUploads(input: {\n attachmentUploads: readonly ResetAttachmentUpload[];\n now: string;\n tx: ClientSQLiteTransactionScope;\n}): Promise<void> {\n for (const attachmentBatch of remoteResetBatches(input.attachmentUploads)) {\n await input.tx\n .insert(documentPendingAttachments)\n .values(\n attachmentBatch.map((attachment) => ({\n ...attachment,\n createdAt: input.now,\n })),\n )\n .run();\n await input.tx\n .delete(documentAttachmentBlobProjection)\n .where(\n or(\n ...attachmentBatch.map((attachment) =>\n and(\n eq(documentAttachmentBlobProjection.localId, attachment.localId),\n eq(documentAttachmentBlobProjection.slotId, attachment.slotId),\n ),\n ),\n ),\n )\n .run();\n }\n}\n\nasync function clearRemoteSyncStateInTransaction(input: {\n plans: Awaited<ReturnType<typeof buildResetPlans>>;\n reset: RemoteResetInput;\n snapshot: RemoteSyncStateSnapshot;\n tx: ClientSQLiteTransactionScope;\n}): Promise<ClearRemoteSyncStateResult> {\n const now = new Date().toISOString();\n const { snapshot } = input;\n await clearScopedRemoteRows({\n attachmentUploads: input.plans.attachmentUploads,\n organizationId: input.reset.organizationId,\n snapshot,\n tx: input.tx,\n });\n await resetRemoteColumns({ now, reset: input.reset, snapshot, tx: input.tx });\n await queueResetDocumentUpdates({\n documentUpdates: input.plans.documentUpdates,\n now,\n tx: input.tx,\n });\n const queuedContainerCreateCount = await queueResetContainerCreates({\n now,\n reset: input.reset,\n snapshot,\n tx: input.tx,\n });\n await queueResetAttachmentUploads({\n attachmentUploads: input.plans.attachmentUploads,\n now,\n tx: input.tx,\n });\n return {\n clearedContainerCreateIntentCount:\n snapshot.clearedContainerCreateIntentCount,\n clearedContainerMoveIntentCount: snapshot.clearedContainerMoveIntentCount,\n clearedDocumentMoveIntentCount: snapshot.clearedDocumentMoveIntentCount,\n clearedPrincipalPolicyCount: snapshot.clearedPrincipalPolicyCount,\n clearedSyncCursorCount: snapshot.clearedSyncCursorCount,\n queuedAttachmentUploadCount: input.plans.attachmentUploads.length,\n queuedContainerCreateCount,\n queuedDocumentUpdateCount: input.plans.documentUpdates.length,\n resetContainerCount: snapshot.containerRows.length,\n resetDocumentCount: snapshot.documentRows.length,\n };\n}\n\nexport async function clearRemoteSyncState(\n execSql: ExecSql,\n reset: RemoteResetInput,\n canCommit?: (() => boolean) | undefined,\n): Promise<ClearRemoteSyncStateResult> {\n return runOrganizationPresentationReset(\n execSql,\n reset.organizationId,\n async () => {\n await ensureSqlTables(execSql, clientSqlTables);\n const runtime = getClientSQLitePersistenceRuntime(execSql);\n const resetInTransaction = async (tx: ClientSQLiteTransactionScope) => {\n if (canCommit && !canCommit()) {\n throw new Error(\n \"Remote sync reset aborted: session identity changed\",\n );\n }\n const snapshot = await readRemoteSyncStateSnapshot(\n tx,\n reset.organizationId,\n );\n const plans = await buildResetPlans(tx, snapshot.documentRows);\n return clearRemoteSyncStateInTransaction({\n plans,\n reset,\n snapshot,\n tx,\n });\n };\n if (!canCommit) {\n return runtime.transaction(resetInTransaction);\n }\n const outcome = await runtime.guardedTransaction(\n resetInTransaction,\n canCommit,\n );\n if (!outcome.committed || !outcome.result) {\n throw new Error(\"Remote sync reset aborted: session identity changed\");\n }\n return outcome.result;\n },\n );\n}\n"]}
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { and, eq } from "drizzle-orm";
|
|
2
|
-
import { organizationReadModelPolicyHeads } from "../../sqlite/organizationReadModelSchema.js";
|
|
3
|
-
const POLICY_HEAD_INSERT_BATCH_SIZE = 100;
|
|
4
|
-
function toPolicyHeadRow(input) {
|
|
5
|
-
return {
|
|
6
|
-
organizationId: input.organizationId,
|
|
7
|
-
principalType: input.principalType,
|
|
8
|
-
principalId: input.principalId,
|
|
9
|
-
stateHash: input.currentState.stateHash,
|
|
10
|
-
stateVersion: input.currentState.version,
|
|
11
|
-
keyEpoch: input.currentState.keyEpoch,
|
|
12
|
-
keyFingerprint: input.currentState.keyFingerprint,
|
|
13
|
-
memberCount: input.currentState.memberCount,
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
export async function replaceGroupPolicyHeads(input) {
|
|
17
|
-
await input.tx
|
|
18
|
-
.delete(organizationReadModelPolicyHeads)
|
|
19
|
-
.where(and(eq(organizationReadModelPolicyHeads.organizationId, input.organizationId), eq(organizationReadModelPolicyHeads.principalType, "group")))
|
|
20
|
-
.run();
|
|
21
|
-
const rows = input.groups.groups.flatMap((group) => group.currentState
|
|
22
|
-
? [
|
|
23
|
-
toPolicyHeadRow({
|
|
24
|
-
currentState: group.currentState,
|
|
25
|
-
organizationId: input.organizationId,
|
|
26
|
-
principalId: group.groupId,
|
|
27
|
-
principalType: "group",
|
|
28
|
-
}),
|
|
29
|
-
]
|
|
30
|
-
: []);
|
|
31
|
-
for (let index = 0; index < rows.length; index += POLICY_HEAD_INSERT_BATCH_SIZE) {
|
|
32
|
-
await input.tx
|
|
33
|
-
.insert(organizationReadModelPolicyHeads)
|
|
34
|
-
.values(rows.slice(index, index + POLICY_HEAD_INSERT_BATCH_SIZE))
|
|
35
|
-
.run();
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
export async function applyOrganizationPolicyLane(input) {
|
|
39
|
-
const row = toPolicyHeadRow({
|
|
40
|
-
currentState: input.organizationPolicy.currentState,
|
|
41
|
-
organizationId: input.organizationId,
|
|
42
|
-
principalId: input.organizationId,
|
|
43
|
-
principalType: "organization",
|
|
44
|
-
});
|
|
45
|
-
await input.tx
|
|
46
|
-
.insert(organizationReadModelPolicyHeads)
|
|
47
|
-
.values(row)
|
|
48
|
-
.onConflictDoUpdate({
|
|
49
|
-
target: [
|
|
50
|
-
organizationReadModelPolicyHeads.organizationId,
|
|
51
|
-
organizationReadModelPolicyHeads.principalType,
|
|
52
|
-
organizationReadModelPolicyHeads.principalId,
|
|
53
|
-
],
|
|
54
|
-
set: {
|
|
55
|
-
stateHash: row.stateHash,
|
|
56
|
-
stateVersion: row.stateVersion,
|
|
57
|
-
keyEpoch: row.keyEpoch,
|
|
58
|
-
keyFingerprint: row.keyFingerprint,
|
|
59
|
-
memberCount: row.memberCount,
|
|
60
|
-
},
|
|
61
|
-
})
|
|
62
|
-
.run();
|
|
63
|
-
}
|
|
64
|
-
//# sourceMappingURL=organizationReadModelPolicyHeadPersistence.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"organizationReadModelPolicyHeadPersistence.js","sourceRoot":"","sources":["organizationReadModelPolicyHeadPersistence.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,gCAAgC,EAAE,MAAM,0CAA0C,CAAC;AAI5F,MAAM,6BAA6B,GAAG,GAAG,CAAC;AAE1C,SAAS,eAAe,CAAC,KAKxB;IACC,OAAO;QACL,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,SAAS,EAAE,KAAK,CAAC,YAAY,CAAC,SAAS;QACvC,YAAY,EAAE,KAAK,CAAC,YAAY,CAAC,OAAO;QACxC,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAC,QAAQ;QACrC,cAAc,EAAE,KAAK,CAAC,YAAY,CAAC,cAAc;QACjD,WAAW,EAAE,KAAK,CAAC,YAAY,CAAC,WAAW;KAC5C,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,KAI7C;IACC,MAAM,KAAK,CAAC,EAAE;SACX,MAAM,CAAC,gCAAgC,CAAC;SACxC,KAAK,CACJ,GAAG,CACD,EAAE,CACA,gCAAgC,CAAC,cAAc,EAC/C,KAAK,CAAC,cAAc,CACrB,EACD,EAAE,CAAC,gCAAgC,CAAC,aAAa,EAAE,OAAO,CAAC,CAC5D,CACF;SACA,GAAG,EAAE,CAAC;IAET,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CACjD,KAAK,CAAC,YAAY;QAChB,CAAC,CAAC;YACE,eAAe,CAAC;gBACd,YAAY,EAAE,KAAK,CAAC,YAAY;gBAChC,cAAc,EAAE,KAAK,CAAC,cAAc;gBACpC,WAAW,EAAE,KAAK,CAAC,OAAO;gBAC1B,aAAa,EAAE,OAAO;aACvB,CAAC;SACH;QACH,CAAC,CAAC,EAAE,CACP,CAAC;IACF,KACE,IAAI,KAAK,GAAG,CAAC,EACb,KAAK,GAAG,IAAI,CAAC,MAAM,EACnB,KAAK,IAAI,6BAA6B,EACtC,CAAC;QACD,MAAM,KAAK,CAAC,EAAE;aACX,MAAM,CAAC,gCAAgC,CAAC;aACxC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,6BAA6B,CAAC,CAAC;aAChE,GAAG,EAAE,CAAC;IACX,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAAC,KAIjD;IACC,MAAM,GAAG,GAAG,eAAe,CAAC;QAC1B,YAAY,EAAE,KAAK,CAAC,kBAAkB,CAAC,YAAY;QACnD,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,WAAW,EAAE,KAAK,CAAC,cAAc;QACjC,aAAa,EAAE,cAAc;KAC9B,CAAC,CAAC;IACH,MAAM,KAAK,CAAC,EAAE;SACX,MAAM,CAAC,gCAAgC,CAAC;SACxC,MAAM,CAAC,GAAG,CAAC;SACX,kBAAkB,CAAC;QAClB,MAAM,EAAE;YACN,gCAAgC,CAAC,cAAc;YAC/C,gCAAgC,CAAC,aAAa;YAC9C,gCAAgC,CAAC,WAAW;SAC7C;QACD,GAAG,EAAE;YACH,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,YAAY,EAAE,GAAG,CAAC,YAAY;YAC9B,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,cAAc,EAAE,GAAG,CAAC,cAAc;YAClC,WAAW,EAAE,GAAG,CAAC,WAAW;SAC7B;KACF,CAAC;SACD,GAAG,EAAE,CAAC;AACX,CAAC","sourcesContent":["import type {\n ListOrganizationGroupsResponse,\n OrganizationGroupCurrentStateResponse,\n OrganizationReadModelOrganizationPolicyResponse,\n} from \"@tearleads/validators/response\";\nimport { and, eq } from \"drizzle-orm\";\nimport { organizationReadModelPolicyHeads } from \"../../sqlite/organizationReadModelSchema\";\nimport type { ClientSQLiteTransactionScope } from \"../../sqlite/sqlitePersistenceRuntime\";\nimport type { OrganizationReadModelPolicyHead } from \"./organizationReadModelProjection\";\n\nconst POLICY_HEAD_INSERT_BATCH_SIZE = 100;\n\nfunction toPolicyHeadRow(input: {\n readonly currentState: OrganizationGroupCurrentStateResponse;\n readonly organizationId: string;\n readonly principalId: string;\n readonly principalType: OrganizationReadModelPolicyHead[\"principalType\"];\n}) {\n return {\n organizationId: input.organizationId,\n principalType: input.principalType,\n principalId: input.principalId,\n stateHash: input.currentState.stateHash,\n stateVersion: input.currentState.version,\n keyEpoch: input.currentState.keyEpoch,\n keyFingerprint: input.currentState.keyFingerprint,\n memberCount: input.currentState.memberCount,\n };\n}\n\nexport async function replaceGroupPolicyHeads(input: {\n readonly groups: ListOrganizationGroupsResponse;\n readonly organizationId: string;\n readonly tx: ClientSQLiteTransactionScope;\n}): Promise<void> {\n await input.tx\n .delete(organizationReadModelPolicyHeads)\n .where(\n and(\n eq(\n organizationReadModelPolicyHeads.organizationId,\n input.organizationId,\n ),\n eq(organizationReadModelPolicyHeads.principalType, \"group\"),\n ),\n )\n .run();\n\n const rows = input.groups.groups.flatMap((group) =>\n group.currentState\n ? [\n toPolicyHeadRow({\n currentState: group.currentState,\n organizationId: input.organizationId,\n principalId: group.groupId,\n principalType: \"group\",\n }),\n ]\n : [],\n );\n for (\n let index = 0;\n index < rows.length;\n index += POLICY_HEAD_INSERT_BATCH_SIZE\n ) {\n await input.tx\n .insert(organizationReadModelPolicyHeads)\n .values(rows.slice(index, index + POLICY_HEAD_INSERT_BATCH_SIZE))\n .run();\n }\n}\n\nexport async function applyOrganizationPolicyLane(input: {\n readonly organizationId: string;\n readonly organizationPolicy: OrganizationReadModelOrganizationPolicyResponse;\n readonly tx: ClientSQLiteTransactionScope;\n}): Promise<void> {\n const row = toPolicyHeadRow({\n currentState: input.organizationPolicy.currentState,\n organizationId: input.organizationId,\n principalId: input.organizationId,\n principalType: \"organization\",\n });\n await input.tx\n .insert(organizationReadModelPolicyHeads)\n .values(row)\n .onConflictDoUpdate({\n target: [\n organizationReadModelPolicyHeads.organizationId,\n organizationReadModelPolicyHeads.principalType,\n organizationReadModelPolicyHeads.principalId,\n ],\n set: {\n stateHash: row.stateHash,\n stateVersion: row.stateVersion,\n keyEpoch: row.keyEpoch,\n keyFingerprint: row.keyFingerprint,\n memberCount: row.memberCount,\n },\n })\n .run();\n}\n"]}
|