@opengeni/db 0.28.9 → 0.31.1

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.
Files changed (163) hide show
  1. package/dist/attached-browser-devices.d.ts +42 -0
  2. package/dist/attempt-tool-catalogs.d.ts +16 -0
  3. package/dist/browser-auth.d.ts +91 -0
  4. package/dist/browser-identities.d.ts +128 -0
  5. package/dist/browser-sessions.d.ts +272 -0
  6. package/dist/browser-state-artifacts.d.ts +17 -0
  7. package/dist/capability-components.d.ts +37 -0
  8. package/dist/capability-integrations.d.ts +192 -0
  9. package/dist/chunk-F5FT7BEZ.js +3535 -0
  10. package/dist/chunk-F5FT7BEZ.js.map +1 -0
  11. package/dist/chunk-ISI2TIUG.js +639 -0
  12. package/dist/chunk-ISI2TIUG.js.map +1 -0
  13. package/dist/chunk-MWDVXQOL.js +11639 -0
  14. package/dist/chunk-MWDVXQOL.js.map +1 -0
  15. package/dist/chunk-NBE6CHRI.js +955 -0
  16. package/dist/chunk-NBE6CHRI.js.map +1 -0
  17. package/dist/{chunk-VHBFHMPC.js → chunk-YHZXQ7HP.js} +754 -11
  18. package/dist/chunk-YHZXQ7HP.js.map +1 -0
  19. package/dist/codemode-operations.d.ts +117 -0
  20. package/dist/codex-token-resolver.d.ts +2 -2
  21. package/dist/company-profile-schema.d.ts +798 -0
  22. package/dist/company-profile.d.ts +268 -0
  23. package/dist/computer-sessions.d.ts +109 -0
  24. package/dist/connection-token-resolver.d.ts +9 -4
  25. package/dist/database.d.ts +52 -3
  26. package/dist/editable-artifact-durable-export.d.ts +153 -0
  27. package/dist/editable-artifact-durable-export.js +788 -0
  28. package/dist/editable-artifact-durable-export.js.map +1 -0
  29. package/dist/editable-artifact-materialization.d.ts +123 -0
  30. package/dist/editable-artifacts-schema.d.ts +4152 -0
  31. package/dist/editable-artifacts.d.ts +610 -0
  32. package/dist/editable-artifacts.js +26 -0
  33. package/dist/editable-artifacts.js.map +1 -0
  34. package/dist/generated-images.d.ts +139 -0
  35. package/dist/index.d.ts +698 -111
  36. package/dist/index.js +27573 -10322
  37. package/dist/index.js.map +1 -1
  38. package/dist/insights.d.ts +51 -4
  39. package/dist/integration-bindings.d.ts +70 -0
  40. package/dist/integration-features.d.ts +99 -0
  41. package/dist/interaction-revisions.d.ts +3 -0
  42. package/dist/interaction-schema.d.ts +5372 -0
  43. package/dist/knowledge-source-sync-schema.d.ts +1679 -0
  44. package/dist/knowledge-source-sync.d.ts +274 -0
  45. package/dist/memory-governance.d.ts +2 -2
  46. package/dist/memory-slack-delivery.d.ts +101 -0
  47. package/dist/new-session-drafts.d.ts +2 -2
  48. package/dist/pack-components.d.ts +76 -0
  49. package/dist/pack-installations.d.ts +86 -0
  50. package/dist/persistence-errors.d.ts +3 -3
  51. package/dist/plugin-packages.d.ts +126 -0
  52. package/dist/preference-registry.d.ts +1 -1
  53. package/dist/provision-roles.d.ts +9 -1
  54. package/dist/provision-roles.js +1 -1
  55. package/dist/runtime-posture.d.ts +18 -6
  56. package/dist/schema.d.ts +18342 -9099
  57. package/dist/schema.js +165 -1
  58. package/dist/scoped-knowledge.d.ts +97 -1
  59. package/dist/session-control.d.ts +4 -4
  60. package/dist/session-queue-commands.d.ts +19 -11
  61. package/dist/session-realtime-context.d.ts +2 -2
  62. package/dist/session-realtime-ledger.d.ts +4 -4
  63. package/dist/session-realtime-mirror.d.ts +2 -2
  64. package/dist/session-realtime-state.d.ts +1 -1
  65. package/dist/session-realtime-terminal.d.ts +1 -1
  66. package/dist/session-realtime.d.ts +7 -7
  67. package/dist/session-tool-call-settlement.d.ts +1 -1
  68. package/dist/slack-user-link-access.d.ts +54 -0
  69. package/dist/transcription-recordings.d.ts +2 -2
  70. package/dist/turn-initiator.d.ts +2 -2
  71. package/dist/video-generation.d.ts +216 -0
  72. package/dist/video-generation.js +66 -0
  73. package/dist/video-generation.js.map +1 -0
  74. package/dist/workspace-artifacts.d.ts +1 -1
  75. package/dist/workspace-instruction-policies.d.ts +1 -1
  76. package/dist/workspace-learning-policy-schema.d.ts +932 -0
  77. package/dist/workspace-learning-policy.d.ts +161 -0
  78. package/drizzle/0183_model_call_provider_cost_estimates.sql +39 -0
  79. package/drizzle/0184_sandbox_drain_teardown_fence.sql +682 -0
  80. package/drizzle/0185_temporal_schedule_cleanup_outbox.sql +168 -0
  81. package/drizzle/0186_sandbox_capture_provider_contract.sql +400 -0
  82. package/drizzle/0187_generated_image_artifacts.sql +173 -0
  83. package/drizzle/0188_image_generation_retention_failure.sql +25 -0
  84. package/drizzle/0189_retained_session_image_formats.sql +13 -0
  85. package/drizzle/0190_timeline_annotations.sql +31 -0
  86. package/drizzle/0191_editable_artifact_engine.sql +3853 -0
  87. package/drizzle/0192_editable_artifact_live_tickets.sql +338 -0
  88. package/drizzle/0193_editable_artifact_authorization.sql +190 -0
  89. package/drizzle/0194_editable_artifact_durable_exports.sql +160 -0
  90. package/drizzle/0195_editable_artifact_import_authorization.sql +203 -0
  91. package/drizzle/0196_rig_provider_images.sql +152 -0
  92. package/drizzle/0197_knowledge_source_sync_schedules.sql +523 -0
  93. package/drizzle/0198_memory_slack_publication_delivery.sql +393 -0
  94. package/drizzle/0199_workspace_learning_policy.sql +980 -0
  95. package/drizzle/0201_company_profile_authority.sql +849 -0
  96. package/drizzle/0202_document_index_checkpoints.sql +85 -0
  97. package/drizzle/0203_durable_video_generation.sql +353 -0
  98. package/drizzle/0204_video_generation_funding.sql +44 -0
  99. package/drizzle/0205_attempt_tool_catalogs.sql +230 -0
  100. package/drizzle/0206_browser_sessions.sql +646 -0
  101. package/drizzle/0207_browser_identities.sql +379 -0
  102. package/drizzle/0208_attached_browser_devices.sql +165 -0
  103. package/drizzle/0209_computer_sessions.sql +575 -0
  104. package/drizzle/0210_browser_auth_network_interventions.sql +441 -0
  105. package/drizzle/0211_editable_artifact_session_links.sql +58 -0
  106. package/drizzle/0212_slack_installation_bindings.sql +348 -0
  107. package/drizzle/0213_slack_user_link_access_requests.sql +177 -0
  108. package/drizzle/0214_session_activity_commit_gate.sql +262 -0
  109. package/drizzle/0215_capabilities_platform.sql +980 -0
  110. package/drizzle/0216_pack_component_ownership.sql +235 -0
  111. package/drizzle/0217_capability_definition_delete_authority.sql +32 -0
  112. package/package.json +18 -5
  113. package/src/attached-browser-devices.ts +371 -0
  114. package/src/attempt-tool-catalogs.ts +131 -0
  115. package/src/browser-auth.ts +1896 -0
  116. package/src/browser-identities.ts +1168 -0
  117. package/src/browser-sessions.ts +2005 -0
  118. package/src/browser-state-artifacts.ts +59 -0
  119. package/src/capability-components.ts +166 -0
  120. package/src/capability-integrations.ts +1663 -0
  121. package/src/codemode-operations.ts +674 -0
  122. package/src/company-profile-schema.ts +143 -0
  123. package/src/company-profile.ts +968 -0
  124. package/src/computer-sessions.ts +1130 -0
  125. package/src/connection-token-resolver.ts +270 -25
  126. package/src/database.ts +427 -23
  127. package/src/editable-artifact-durable-export.ts +1201 -0
  128. package/src/editable-artifact-materialization.ts +893 -0
  129. package/src/editable-artifacts-schema.ts +879 -0
  130. package/src/editable-artifacts.ts +5404 -0
  131. package/src/generated-images.ts +740 -0
  132. package/src/index.ts +5917 -1182
  133. package/src/insights.ts +160 -13
  134. package/src/integration-bindings.ts +455 -0
  135. package/src/integration-features.ts +859 -0
  136. package/src/interaction-revisions.ts +40 -0
  137. package/src/interaction-schema.ts +1303 -0
  138. package/src/knowledge-source-sync-schema.ts +192 -0
  139. package/src/knowledge-source-sync.ts +1922 -0
  140. package/src/memory-slack-delivery.ts +801 -0
  141. package/src/pack-components.ts +954 -0
  142. package/src/pack-installations.ts +929 -0
  143. package/src/persistence-errors.ts +4 -7
  144. package/src/plugin-packages.ts +1186 -0
  145. package/src/provision-roles.ts +302 -1
  146. package/src/runtime-posture-cli.ts +9 -0
  147. package/src/runtime-posture.ts +508 -5
  148. package/src/schema.ts +5117 -3119
  149. package/src/scoped-knowledge-schema.ts +1 -1
  150. package/src/scoped-knowledge.ts +655 -3
  151. package/src/session-control.ts +8 -5
  152. package/src/session-queue-commands.ts +187 -14
  153. package/src/session-realtime-context.ts +2 -2
  154. package/src/session-realtime-ledger.ts +3 -3
  155. package/src/session-realtime.ts +7 -7
  156. package/src/session-tool-call-settlement.ts +9 -0
  157. package/src/slack-user-link-access.ts +702 -0
  158. package/src/video-generation.ts +1452 -0
  159. package/src/workspace-learning-policy-schema.ts +139 -0
  160. package/src/workspace-learning-policy.ts +595 -0
  161. package/dist/chunk-P6CUHXQZ.js +0 -7248
  162. package/dist/chunk-P6CUHXQZ.js.map +0 -1
  163. package/dist/chunk-VHBFHMPC.js.map +0 -1
@@ -0,0 +1,879 @@
1
+ import { sql } from "drizzle-orm";
2
+ import {
3
+ bigint,
4
+ boolean,
5
+ check,
6
+ customType,
7
+ index,
8
+ integer,
9
+ jsonb,
10
+ pgTable,
11
+ primaryKey,
12
+ text,
13
+ timestamp,
14
+ uniqueIndex,
15
+ uuid,
16
+ } from "drizzle-orm/pg-core";
17
+
18
+ // Tenant/workspace and cross-table foreign keys, FORCE-RLS policies, immutable
19
+ // history guards, and deferred sequence/causal validation live in migration
20
+ // 0184. This leaf intentionally does not import schema.ts, avoiding a cycle.
21
+
22
+ const bytea = customType<{ data: Uint8Array; driverData: Uint8Array }>({
23
+ dataType: () => "bytea",
24
+ });
25
+
26
+ export type EditableArtifactCausalFrontierRow = Array<{
27
+ replicaId: string;
28
+ counter: number;
29
+ }>;
30
+
31
+ export type EditableArtifactOutboxEventRow = Record<string, unknown>;
32
+ export type EditableArtifactIdempotencyResultRow = Record<string, unknown>;
33
+
34
+ function scopeColumns() {
35
+ return {
36
+ accountId: uuid("account_id").notNull(),
37
+ workspaceId: uuid("workspace_id").notNull(),
38
+ };
39
+ }
40
+
41
+ const stableIdSql = (column: unknown) => sql`${column} ~ '^[0-9a-f]{32}$' and ${column} !~ '^0+$'`;
42
+ const replicaIdSql = (column: unknown) => sql`${column} ~ '^[0-9a-f]{16}$' and ${column} !~ '^0+$'`;
43
+ const sha256Sql = (column: unknown) => sql`${column} ~ '^sha256:[0-9a-f]{64}$'`;
44
+
45
+ /** Local monotonic fence for workspace-scoped artifact creation policy. */
46
+ export const editableArtifactScopeAuthorizationHeads = pgTable(
47
+ "editable_artifact_scope_authorization_heads",
48
+ {
49
+ ...scopeColumns(),
50
+ createRevision: bigint("create_revision", { mode: "number" }).notNull().default(1),
51
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
52
+ },
53
+ (table) => ({
54
+ pk: primaryKey({
55
+ name: "editable_artifact_scope_authorization_heads_pk",
56
+ columns: [table.accountId, table.workspaceId],
57
+ }),
58
+ revisionValid: check(
59
+ "editable_artifact_scope_authorization_heads_revision_chk",
60
+ sql`${table.createRevision} between 1 and 9007199254740991`,
61
+ ),
62
+ }),
63
+ );
64
+
65
+ /**
66
+ * One-use live admission capabilities. The bearer token is never persisted;
67
+ * only its digest is stored, and production access is through owner-defined
68
+ * atomic routines rather than direct table grants.
69
+ */
70
+ export const editableArtifactLiveTickets = pgTable(
71
+ "editable_artifact_live_tickets",
72
+ {
73
+ tokenDigest: text("token_digest").primaryKey(),
74
+ ...scopeColumns(),
75
+ artifactId: text("artifact_id").notNull(),
76
+ modality: text("modality", {
77
+ enum: ["spreadsheet", "presentation", "document"],
78
+ }).notNull(),
79
+ actorKind: text("actor_kind", { enum: ["human", "agent", "service"] }).notNull(),
80
+ actorSubjectId: text("actor_subject_id").notNull(),
81
+ replicaId: text("replica_id").notNull(),
82
+ agentSessionId: text("agent_session_id"),
83
+ agentTurnId: text("agent_turn_id"),
84
+ agentAttemptId: text("agent_attempt_id"),
85
+ agentGeneration: integer("agent_generation"),
86
+ serviceName: text("service_name"),
87
+ allowEdit: boolean("allow_edit").notNull(),
88
+ protocolVersion: integer("protocol_version").notNull(),
89
+ issuedAt: timestamp("issued_at", { withTimezone: true }).notNull(),
90
+ expiresAt: timestamp("expires_at", { withTimezone: true }).notNull(),
91
+ },
92
+ (table) => ({
93
+ expiry: index("editable_artifact_live_tickets_expiry_idx").on(
94
+ table.expiresAt,
95
+ table.tokenDigest,
96
+ ),
97
+ digestValid: check("editable_artifact_live_tickets_digest_chk", sha256Sql(table.tokenDigest)),
98
+ identityValid: check(
99
+ "editable_artifact_live_tickets_identity_chk",
100
+ sql`${stableIdSql(table.artifactId)} and ${replicaIdSql(table.replicaId)}`,
101
+ ),
102
+ }),
103
+ );
104
+
105
+ export const editableArtifacts = pgTable(
106
+ "editable_artifacts",
107
+ {
108
+ ...scopeColumns(),
109
+ id: text("id").notNull(),
110
+ modality: text("modality", {
111
+ enum: ["spreadsheet", "presentation", "document"],
112
+ }).notNull(),
113
+ title: text("title").notNull(),
114
+ lifecycleState: text("lifecycle_state", { enum: ["active", "archived"] })
115
+ .notNull()
116
+ .default("active"),
117
+ authorizationRevision: bigint("authorization_revision", { mode: "number" }).notNull(),
118
+ headSequence: bigint("head_sequence", { mode: "number" }).notNull().default(0),
119
+ causalFrontier: jsonb("causal_frontier").$type<EditableArtifactCausalFrontierRow>(),
120
+ stateHash: text("state_hash").notNull(),
121
+ currentSnapshotId: text("current_snapshot_id"),
122
+ createdBySubjectId: text("created_by_subject_id").notNull(),
123
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
124
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
125
+ },
126
+ (table) => ({
127
+ pk: primaryKey({
128
+ name: "editable_artifacts_pk",
129
+ columns: [table.accountId, table.workspaceId, table.id],
130
+ }),
131
+ workspaceTimeline: index("editable_artifacts_workspace_timeline_idx").on(
132
+ table.workspaceId,
133
+ table.lifecycleState,
134
+ table.updatedAt.desc(),
135
+ table.id,
136
+ ),
137
+ identityValid: check("editable_artifacts_identity_chk", stableIdSql(table.id)),
138
+ authorizationRevisionValid: check(
139
+ "editable_artifacts_authorization_revision_chk",
140
+ sql`${table.authorizationRevision} between 1 and 9007199254740991`,
141
+ ),
142
+ headValid: check(
143
+ "editable_artifacts_head_chk",
144
+ sql`${table.headSequence} between 0 and 9007199254740991`,
145
+ ),
146
+ stateHashValid: check("editable_artifacts_state_hash_chk", sha256Sql(table.stateHash)),
147
+ modalityStateValid: check(
148
+ "editable_artifacts_modality_state_chk",
149
+ sql`(${table.modality} = 'spreadsheet' and jsonb_typeof(${table.causalFrontier}) = 'array')
150
+ or (${table.modality} in ('document', 'presentation') and ${table.causalFrontier} is null)`,
151
+ ),
152
+ }),
153
+ );
154
+
155
+ export const editableArtifactTransactions = pgTable(
156
+ "editable_artifact_transactions",
157
+ {
158
+ ...scopeColumns(),
159
+ artifactId: text("artifact_id").notNull(),
160
+ modality: text("modality", {
161
+ enum: ["spreadsheet", "presentation", "document"],
162
+ }).notNull(),
163
+ id: text("id").notNull(),
164
+ clientTransactionId: text("client_transaction_id").notNull(),
165
+ previousLocalTransactionId: text("previous_local_transaction_id"),
166
+ requestHash: text("request_hash").notNull(),
167
+ intentHash: text("intent_hash").notNull(),
168
+ intentEnvelopeVersion: integer("intent_envelope_version").notNull(),
169
+ intentProtocolVersion: integer("intent_protocol_version").notNull(),
170
+ commandProtocolVersion: integer("command_protocol_version").notNull(),
171
+ intentByteSize: integer("intent_byte_size").notNull(),
172
+ intentBytes: bytea("intent_bytes").notNull(),
173
+ parentHeadSequence: bigint("parent_head_sequence", { mode: "number" }).notNull(),
174
+ sequenceStart: bigint("sequence_start", { mode: "number" }).notNull(),
175
+ sequenceEnd: bigint("sequence_end", { mode: "number" }).notNull(),
176
+ priorStateHash: text("prior_state_hash").notNull(),
177
+ causalBase: jsonb("causal_base").$type<EditableArtifactCausalFrontierRow>(),
178
+ resolvedCausalBase: jsonb("resolved_causal_base").$type<EditableArtifactCausalFrontierRow>(),
179
+ resultingCausalFrontier: jsonb(
180
+ "resulting_causal_frontier",
181
+ ).$type<EditableArtifactCausalFrontierRow>(),
182
+ selectiveUndoTargets: jsonb("selective_undo_targets").$type<string[]>(),
183
+ stateHash: text("state_hash").notNull(),
184
+ operationCount: integer("operation_count"),
185
+ operationIds: jsonb("operation_ids").$type<string[]>(),
186
+ actorKind: text("actor_kind", { enum: ["human", "agent", "service"] }).notNull(),
187
+ actorSubjectId: text("actor_subject_id").notNull(),
188
+ actorKey: text("actor_key").notNull(),
189
+ actorKeyDigest: bytea("actor_key_digest").generatedAlwaysAs(
190
+ sql`opengeni_private.editable_artifact_text_sha256(actor_key)`,
191
+ ),
192
+ replicaId: text("replica_id").notNull(),
193
+ replicaCounter: bigint("replica_counter", { mode: "number" }).notNull(),
194
+ agentSessionId: text("agent_session_id"),
195
+ agentTurnId: text("agent_turn_id"),
196
+ agentAttemptId: text("agent_attempt_id"),
197
+ agentGeneration: integer("agent_generation"),
198
+ serviceName: text("service_name"),
199
+ kernelVersion: text("kernel_version").notNull(),
200
+ modelSchemaVersion: integer("model_schema_version").notNull(),
201
+ operationProtocolVersion: integer("operation_protocol_version"),
202
+ commitProtocolVersion: integer("commit_protocol_version"),
203
+ priorNativeRevision: bigint("prior_native_revision", { mode: "number" }),
204
+ nativeRevision: bigint("native_revision", { mode: "number" }),
205
+ commandCount: integer("command_count"),
206
+ nativeReceiptByteSize: integer("native_receipt_byte_size"),
207
+ nativeReceiptHash: text("native_receipt_hash"),
208
+ nativeReceiptBytes: bytea("native_receipt_bytes"),
209
+ committedTransactionByteSize: integer("committed_transaction_byte_size").notNull(),
210
+ committedTransactionHash: text("committed_transaction_hash").notNull(),
211
+ committedTransactionBytes: bytea("committed_transaction_bytes").notNull(),
212
+ committedAt: timestamp("committed_at", { withTimezone: true }).notNull().defaultNow(),
213
+ },
214
+ (table) => ({
215
+ pk: primaryKey({
216
+ name: "editable_artifact_transactions_pk",
217
+ columns: [table.accountId, table.workspaceId, table.artifactId, table.id],
218
+ }),
219
+ actorClientTransaction: uniqueIndex("editable_artifact_transactions_actor_client_uq").on(
220
+ table.accountId,
221
+ table.workspaceId,
222
+ table.artifactId,
223
+ table.actorKeyDigest,
224
+ table.clientTransactionId,
225
+ ),
226
+ predecessorIdentity: uniqueIndex("editable_artifact_transactions_predecessor_identity_uq").on(
227
+ table.accountId,
228
+ table.workspaceId,
229
+ table.artifactId,
230
+ table.actorKeyDigest,
231
+ table.replicaId,
232
+ table.clientTransactionId,
233
+ ),
234
+ exactReceiptAuthority: uniqueIndex(
235
+ "editable_artifact_transactions_exact_receipt_authority_uq",
236
+ ).on(
237
+ table.accountId,
238
+ table.workspaceId,
239
+ table.artifactId,
240
+ table.id,
241
+ table.actorKeyDigest,
242
+ table.clientTransactionId,
243
+ table.requestHash,
244
+ ),
245
+ replicaCounter: uniqueIndex("editable_artifact_transactions_replica_counter_uq").on(
246
+ table.accountId,
247
+ table.workspaceId,
248
+ table.artifactId,
249
+ table.replicaId,
250
+ table.replicaCounter,
251
+ ),
252
+ sequence: uniqueIndex("editable_artifact_transactions_sequence_uq").on(
253
+ table.accountId,
254
+ table.workspaceId,
255
+ table.artifactId,
256
+ table.sequenceStart,
257
+ table.sequenceEnd,
258
+ ),
259
+ replay: index("editable_artifact_transactions_replay_idx").on(
260
+ table.workspaceId,
261
+ table.artifactId,
262
+ table.sequenceStart,
263
+ ),
264
+ idValid: check("editable_artifact_transactions_id_chk", stableIdSql(table.id)),
265
+ replicaValid: check(
266
+ "editable_artifact_transactions_replica_chk",
267
+ replicaIdSql(table.replicaId),
268
+ ),
269
+ hashValid: check(
270
+ "editable_artifact_transactions_hash_chk",
271
+ sql`${sha256Sql(table.requestHash)} and ${sha256Sql(table.intentHash)}
272
+ and ${table.intentHash} = ${table.requestHash}
273
+ and ${table.intentEnvelopeVersion} = 1
274
+ and ${table.intentProtocolVersion} = 1
275
+ and ${table.commandProtocolVersion} > 0
276
+ and ${table.intentByteSize} between 8 and 5242880
277
+ and octet_length(${table.intentBytes}) = ${table.intentByteSize}
278
+ and substring(${table.intentBytes} from 1 for 8) = convert_to('OGATX001', 'UTF8')
279
+ and ${table.intentHash} = 'sha256:' || encode(sha256(${table.intentBytes}), 'hex')
280
+ and ${sha256Sql(table.priorStateHash)}
281
+ and ${sha256Sql(table.stateHash)}
282
+ and ${sha256Sql(table.committedTransactionHash)}
283
+ and ${table.parentHeadSequence} between 0 and 9007199254740991
284
+ and ${table.sequenceStart} = ${table.parentHeadSequence} + 1
285
+ and ${table.committedTransactionByteSize} between 1 and 8388608
286
+ and octet_length(${table.committedTransactionBytes}) = ${table.committedTransactionByteSize}
287
+ and ${table.committedTransactionHash} =
288
+ 'sha256:' || encode(sha256(${table.committedTransactionBytes}), 'hex')
289
+ and (
290
+ (${table.modality} = 'spreadsheet'
291
+ and ${table.operationCount} between 1 and 4096
292
+ and ${table.sequenceEnd} = ${table.sequenceStart} + ${table.operationCount} - 1
293
+ and jsonb_typeof(${table.causalBase}) = 'array'
294
+ and jsonb_typeof(${table.resolvedCausalBase}) = 'array'
295
+ and jsonb_typeof(${table.resultingCausalFrontier}) = 'array'
296
+ and jsonb_typeof(${table.selectiveUndoTargets}) = 'array'
297
+ and jsonb_typeof(${table.operationIds}) = 'array'
298
+ and jsonb_array_length(${table.operationIds}) = ${table.operationCount}
299
+ and ${table.operationProtocolVersion} = 1
300
+ and ${table.commitProtocolVersion} is null
301
+ and ${table.priorNativeRevision} is null
302
+ and ${table.nativeRevision} is null
303
+ and ${table.commandCount} is null
304
+ and ${table.nativeReceiptByteSize} is null
305
+ and ${table.nativeReceiptHash} is null
306
+ and ${table.nativeReceiptBytes} is null
307
+ and substring(${table.committedTransactionBytes} from 1 for 8) = convert_to('OGACO001', 'UTF8'))
308
+ or
309
+ (${table.modality} in ('document', 'presentation')
310
+ and ${table.sequenceEnd} = ${table.sequenceStart}
311
+ and ${table.causalBase} is null
312
+ and ${table.resolvedCausalBase} is null
313
+ and ${table.resultingCausalFrontier} is null
314
+ and ${table.selectiveUndoTargets} is null
315
+ and ${table.operationCount} is null
316
+ and ${table.operationIds} is null
317
+ and ${table.operationProtocolVersion} is null
318
+ and ${table.commitProtocolVersion} = 1
319
+ and ${table.priorNativeRevision} between 0 and 9007199254740991
320
+ and ((${table.modality} = 'document' and (
321
+ (${table.nativeRevision} = ${table.priorNativeRevision}
322
+ and ${table.stateHash} = ${table.priorStateHash})
323
+ or (${table.nativeRevision} = ${table.priorNativeRevision} + 1
324
+ and ${table.stateHash} <> ${table.priorStateHash})
325
+ )) or (${table.modality} = 'presentation'
326
+ and ${table.nativeRevision} = ${table.priorNativeRevision} + 1
327
+ and ${table.stateHash} <> ${table.priorStateHash}))
328
+ and ${table.commandCount} between 1 and 4096
329
+ and ${table.nativeReceiptByteSize} between 1 and 524288
330
+ and octet_length(${table.nativeReceiptBytes}) = ${table.nativeReceiptByteSize}
331
+ and ${sha256Sql(table.nativeReceiptHash)}
332
+ and ${table.nativeReceiptHash} = 'sha256:' || encode(sha256(${table.nativeReceiptBytes}), 'hex')
333
+ and substring(${table.committedTransactionBytes} from 1 for 8) = convert_to('OGAST001', 'UTF8')
334
+ and get_byte(${table.committedTransactionBytes}, 12) =
335
+ case ${table.modality} when 'document' then 1 else 2 end
336
+ and get_byte(${table.committedTransactionBytes}, 13) = 0
337
+ and get_byte(${table.committedTransactionBytes}, 14) = 0
338
+ and get_byte(${table.committedTransactionBytes}, 15) = 0
339
+ and substring(${table.nativeReceiptBytes} from 1 for 8) = convert_to(
340
+ case ${table.modality} when 'document' then 'OGADR001' else 'OGAPR001' end,
341
+ 'UTF8'
342
+ ))
343
+ )`,
344
+ ),
345
+ }),
346
+ );
347
+
348
+ export const editableArtifactOperations = pgTable(
349
+ "editable_artifact_operations",
350
+ {
351
+ ...scopeColumns(),
352
+ artifactId: text("artifact_id").notNull(),
353
+ transactionId: text("transaction_id").notNull(),
354
+ operationId: text("operation_id").notNull(),
355
+ operationIndex: integer("operation_index").notNull(),
356
+ sequence: bigint("sequence", { mode: "number" }).notNull(),
357
+ dotReplicaId: text("dot_replica_id").notNull(),
358
+ dotCounter: bigint("dot_counter", { mode: "number" }).notNull(),
359
+ actorKey: text("actor_key").notNull(),
360
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
361
+ },
362
+ (table) => ({
363
+ pk: primaryKey({
364
+ name: "editable_artifact_operations_pk",
365
+ columns: [
366
+ table.accountId,
367
+ table.workspaceId,
368
+ table.artifactId,
369
+ table.transactionId,
370
+ table.operationIndex,
371
+ ],
372
+ }),
373
+ operationLookup: uniqueIndex("editable_artifact_operations_operation_uq").on(
374
+ table.accountId,
375
+ table.workspaceId,
376
+ table.artifactId,
377
+ table.operationId,
378
+ ),
379
+ replay: uniqueIndex("editable_artifact_operations_sequence_uq").on(
380
+ table.accountId,
381
+ table.workspaceId,
382
+ table.artifactId,
383
+ table.sequence,
384
+ ),
385
+ dotOperation: uniqueIndex("editable_artifact_operations_dot_operation_uq").on(
386
+ table.accountId,
387
+ table.workspaceId,
388
+ table.artifactId,
389
+ table.dotReplicaId,
390
+ table.dotCounter,
391
+ table.operationIndex,
392
+ ),
393
+ idsValid: check(
394
+ "editable_artifact_operations_ids_chk",
395
+ sql`${stableIdSql(table.transactionId)} and ${stableIdSql(table.operationId)}`,
396
+ ),
397
+ dotValid: check(
398
+ "editable_artifact_operations_dot_chk",
399
+ sql`${replicaIdSql(table.dotReplicaId)} and ${table.dotCounter} > 0`,
400
+ ),
401
+ positionValid: check(
402
+ "editable_artifact_operations_position_chk",
403
+ sql`${table.operationIndex} between 0 and 4095
404
+ and ${table.sequence} between 1 and 9007199254740991`,
405
+ ),
406
+ }),
407
+ );
408
+
409
+ export const editableArtifactIdempotencyReceipts = pgTable(
410
+ "editable_artifact_idempotency_receipts",
411
+ {
412
+ ...scopeColumns(),
413
+ id: text("id").notNull(),
414
+ artifactId: text("artifact_id").notNull(),
415
+ operationKind: text("operation_kind", {
416
+ enum: ["create", "import", "edit", "snapshot", "version", "materialize"],
417
+ }).notNull(),
418
+ authorityKey: text("authority_key").notNull(),
419
+ authorityKeyDigest: bytea("authority_key_digest").generatedAlwaysAs(
420
+ sql`opengeni_private.editable_artifact_text_sha256(authority_key)`,
421
+ ),
422
+ idempotencyKey: text("idempotency_key").notNull(),
423
+ requestHash: text("request_hash").notNull(),
424
+ resourceType: text("resource_type", {
425
+ enum: ["artifact", "transaction", "snapshot", "artifact_version", "materialization_job"],
426
+ }).notNull(),
427
+ resourceId: text("resource_id").notNull(),
428
+ serverTransactionId: text("server_transaction_id"),
429
+ result: jsonb("result").$type<EditableArtifactIdempotencyResultRow>().notNull(),
430
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
431
+ },
432
+ (table) => ({
433
+ pk: primaryKey({
434
+ name: "editable_artifact_idempotency_receipts_pk",
435
+ columns: [table.accountId, table.workspaceId, table.id],
436
+ }),
437
+ creationRequest: uniqueIndex("editable_artifact_idempotency_receipts_creation_request_uq")
438
+ .on(
439
+ table.accountId,
440
+ table.workspaceId,
441
+ table.operationKind,
442
+ table.authorityKeyDigest,
443
+ table.idempotencyKey,
444
+ )
445
+ .where(sql`${table.operationKind} in ('create', 'import')`),
446
+ artifactRequest: uniqueIndex("editable_artifact_idempotency_receipts_artifact_request_uq")
447
+ .on(
448
+ table.accountId,
449
+ table.workspaceId,
450
+ table.artifactId,
451
+ table.operationKind,
452
+ table.authorityKeyDigest,
453
+ table.idempotencyKey,
454
+ )
455
+ .where(sql`${table.operationKind} in ('edit', 'snapshot', 'version', 'materialize')`),
456
+ origin: uniqueIndex("editable_artifact_idempotency_receipts_origin_uq")
457
+ .on(table.accountId, table.workspaceId, table.artifactId)
458
+ .where(
459
+ sql`${table.operationKind} in ('create', 'import') and ${table.resourceType} = 'artifact'`,
460
+ ),
461
+ artifactTransaction: index("editable_artifact_idempotency_receipts_transaction_idx").on(
462
+ table.workspaceId,
463
+ table.artifactId,
464
+ table.serverTransactionId,
465
+ ),
466
+ valid: check(
467
+ "editable_artifact_idempotency_receipts_valid_chk",
468
+ sql`${stableIdSql(table.id)} and ${sha256Sql(table.requestHash)}`,
469
+ ),
470
+ }),
471
+ );
472
+
473
+ export const editableArtifactUndoClaims = pgTable(
474
+ "editable_artifact_undo_claims",
475
+ {
476
+ ...scopeColumns(),
477
+ artifactId: text("artifact_id").notNull(),
478
+ targetOperationId: text("target_operation_id").notNull(),
479
+ claimingTransactionId: text("claiming_transaction_id").notNull(),
480
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
481
+ },
482
+ (table) => ({
483
+ pk: primaryKey({
484
+ name: "editable_artifact_undo_claims_pk",
485
+ columns: [table.accountId, table.workspaceId, table.artifactId, table.targetOperationId],
486
+ }),
487
+ transaction: index("editable_artifact_undo_claims_transaction_idx").on(
488
+ table.accountId,
489
+ table.workspaceId,
490
+ table.artifactId,
491
+ table.claimingTransactionId,
492
+ table.targetOperationId,
493
+ ),
494
+ valid: check(
495
+ "editable_artifact_undo_claims_ids_chk",
496
+ sql`${stableIdSql(table.targetOperationId)} and ${stableIdSql(table.claimingTransactionId)}`,
497
+ ),
498
+ }),
499
+ );
500
+
501
+ export const editableArtifactSequenceCheckpoints = pgTable(
502
+ "editable_artifact_sequence_checkpoints",
503
+ {
504
+ ...scopeColumns(),
505
+ artifactId: text("artifact_id").notNull(),
506
+ modality: text("modality", {
507
+ enum: ["spreadsheet", "presentation", "document"],
508
+ }).notNull(),
509
+ headSequence: bigint("head_sequence", { mode: "number" }).notNull(),
510
+ transactionId: text("transaction_id"),
511
+ causalFrontier: jsonb("causal_frontier").$type<EditableArtifactCausalFrontierRow>(),
512
+ nativeRevision: bigint("native_revision", { mode: "number" }),
513
+ stateHash: text("state_hash").notNull(),
514
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
515
+ },
516
+ (table) => ({
517
+ pk: primaryKey({
518
+ name: "editable_artifact_sequence_checkpoints_pk",
519
+ columns: [table.accountId, table.workspaceId, table.artifactId, table.headSequence],
520
+ }),
521
+ transaction: uniqueIndex("editable_artifact_sequence_checkpoints_transaction_uq")
522
+ .on(table.accountId, table.workspaceId, table.artifactId, table.transactionId)
523
+ .where(sql`${table.transactionId} is not null`),
524
+ hashValid: check(
525
+ "editable_artifact_sequence_checkpoints_hash_chk",
526
+ sql`${sha256Sql(table.stateHash)} and (
527
+ (${table.modality} = 'spreadsheet' and jsonb_typeof(${table.causalFrontier}) = 'array'
528
+ and ${table.nativeRevision} is null)
529
+ or (${table.modality} in ('document', 'presentation') and ${table.causalFrontier} is null
530
+ and ${table.nativeRevision} between 0 and 9007199254740991)
531
+ )`,
532
+ ),
533
+ }),
534
+ );
535
+
536
+ export const editableArtifactBlobRefs = pgTable(
537
+ "editable_artifact_blob_refs",
538
+ {
539
+ ...scopeColumns(),
540
+ id: text("id").notNull(),
541
+ artifactId: text("artifact_id").notNull(),
542
+ kind: text("kind", {
543
+ enum: ["snapshot", "original_import", "media", "loss_envelope", "materialization"],
544
+ }).notNull(),
545
+ objectReference: text("object_reference").notNull(),
546
+ byteSize: bigint("byte_size", { mode: "number" }).notNull(),
547
+ contentHash: text("content_hash").notNull(),
548
+ mimeType: text("mime_type").notNull(),
549
+ sourceFileId: uuid("source_file_id"),
550
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
551
+ },
552
+ (table) => ({
553
+ pk: primaryKey({
554
+ name: "editable_artifact_blob_refs_pk",
555
+ columns: [table.accountId, table.workspaceId, table.artifactId, table.id],
556
+ }),
557
+ content: uniqueIndex("editable_artifact_blob_refs_content_uq").on(
558
+ table.accountId,
559
+ table.workspaceId,
560
+ table.artifactId,
561
+ table.kind,
562
+ table.contentHash,
563
+ ),
564
+ exactFacts: uniqueIndex("editable_artifact_blob_refs_exact_facts_uq").on(
565
+ table.accountId,
566
+ table.workspaceId,
567
+ table.artifactId,
568
+ table.id,
569
+ table.byteSize,
570
+ table.contentHash,
571
+ table.mimeType,
572
+ ),
573
+ hashValid: check("editable_artifact_blob_refs_hash_chk", sha256Sql(table.contentHash)),
574
+ sourceKindValid: check(
575
+ "editable_artifact_blob_refs_source_kind_chk",
576
+ sql`(${table.kind} = 'original_import') = (${table.sourceFileId} is not null)`,
577
+ ),
578
+ }),
579
+ );
580
+
581
+ export const editableArtifactSnapshots = pgTable(
582
+ "editable_artifact_snapshots",
583
+ {
584
+ ...scopeColumns(),
585
+ artifactId: text("artifact_id").notNull(),
586
+ modality: text("modality", {
587
+ enum: ["spreadsheet", "presentation", "document"],
588
+ }).notNull(),
589
+ id: text("id").notNull(),
590
+ blobRefId: text("blob_ref_id").notNull(),
591
+ byteSize: bigint("byte_size", { mode: "number" }).notNull(),
592
+ contentHash: text("content_hash").notNull(),
593
+ mimeType: text("mime_type")
594
+ .notNull()
595
+ .default("application/vnd.opengeni.editable-artifact-snapshot"),
596
+ coveredHeadSequence: bigint("covered_head_sequence", { mode: "number" }).notNull(),
597
+ coveredCausalFrontier:
598
+ jsonb("covered_causal_frontier").$type<EditableArtifactCausalFrontierRow>(),
599
+ stateHash: text("state_hash").notNull(),
600
+ modelSchemaVersion: integer("model_schema_version").notNull(),
601
+ operationProtocolVersion: integer("operation_protocol_version"),
602
+ kernelVersion: text("kernel_version").notNull(),
603
+ crdtStateVersion: integer("crdt_state_version"),
604
+ nativeRevision: bigint("native_revision", { mode: "number" }),
605
+ verifiedAt: timestamp("verified_at", { withTimezone: true }).notNull(),
606
+ publishedAt: timestamp("published_at", { withTimezone: true }).notNull().defaultNow(),
607
+ },
608
+ (table) => ({
609
+ pk: primaryKey({
610
+ name: "editable_artifact_snapshots_pk",
611
+ columns: [table.accountId, table.workspaceId, table.artifactId, table.id],
612
+ }),
613
+ content: uniqueIndex("editable_artifact_snapshots_content_uq").on(
614
+ table.accountId,
615
+ table.workspaceId,
616
+ table.artifactId,
617
+ table.contentHash,
618
+ table.coveredHeadSequence,
619
+ ),
620
+ sourceManifest: uniqueIndex("editable_artifact_snapshots_source_manifest_uq").on(
621
+ table.accountId,
622
+ table.workspaceId,
623
+ table.artifactId,
624
+ table.id,
625
+ table.coveredHeadSequence,
626
+ table.stateHash,
627
+ ),
628
+ coverage: index("editable_artifact_snapshots_coverage_idx").on(
629
+ table.workspaceId,
630
+ table.artifactId,
631
+ table.coveredHeadSequence.desc(),
632
+ ),
633
+ valid: check(
634
+ "editable_artifact_snapshots_valid_chk",
635
+ sql`${stableIdSql(table.id)} and ${sha256Sql(table.contentHash)} and ${sha256Sql(table.stateHash)}
636
+ and (
637
+ (${table.modality} = 'spreadsheet'
638
+ and jsonb_typeof(${table.coveredCausalFrontier}) = 'array'
639
+ and ${table.operationProtocolVersion} = 1
640
+ and ${table.crdtStateVersion} > 0
641
+ and ${table.nativeRevision} is null)
642
+ or (${table.modality} in ('document', 'presentation')
643
+ and ${table.coveredCausalFrontier} is null
644
+ and ${table.operationProtocolVersion} is null
645
+ and ${table.crdtStateVersion} is null
646
+ and ${table.nativeRevision} between 0 and 9007199254740991)
647
+ )`,
648
+ ),
649
+ }),
650
+ );
651
+
652
+ export const editableArtifactVersions = pgTable(
653
+ "editable_artifact_versions",
654
+ {
655
+ ...scopeColumns(),
656
+ artifactId: text("artifact_id").notNull(),
657
+ id: text("id").notNull(),
658
+ snapshotId: text("snapshot_id"),
659
+ headSequence: bigint("head_sequence", { mode: "number" }).notNull(),
660
+ causalFrontier: jsonb("causal_frontier").$type<EditableArtifactCausalFrontierRow>(),
661
+ nativeRevision: bigint("native_revision", { mode: "number" }),
662
+ stateHash: text("state_hash").notNull(),
663
+ name: text("name").notNull(),
664
+ pinned: boolean("pinned").notNull().default(true),
665
+ createdBySubjectId: text("created_by_subject_id").notNull(),
666
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
667
+ },
668
+ (table) => ({
669
+ pk: primaryKey({
670
+ name: "editable_artifact_versions_pk",
671
+ columns: [table.accountId, table.workspaceId, table.artifactId, table.id],
672
+ }),
673
+ timeline: index("editable_artifact_versions_timeline_idx").on(
674
+ table.workspaceId,
675
+ table.artifactId,
676
+ table.createdAt.desc(),
677
+ table.id,
678
+ ),
679
+ valid: check(
680
+ "editable_artifact_versions_valid_chk",
681
+ sql`${stableIdSql(table.id)} and ${sha256Sql(table.stateHash)}
682
+ and ((${table.causalFrontier} is not null and ${table.nativeRevision} is null)
683
+ or (${table.causalFrontier} is null
684
+ and ${table.nativeRevision} between 0 and 9007199254740991))`,
685
+ ),
686
+ }),
687
+ );
688
+
689
+ export const editableArtifactMaterializationJobs = pgTable(
690
+ "editable_artifact_materialization_jobs",
691
+ {
692
+ ...scopeColumns(),
693
+ artifactId: text("artifact_id").notNull(),
694
+ id: text("id").notNull(),
695
+ versionId: text("version_id"),
696
+ inputSnapshotId: text("input_snapshot_id").notNull(),
697
+ targetHeadSequence: bigint("target_head_sequence", { mode: "number" }).notNull(),
698
+ stateHash: text("state_hash").notNull(),
699
+ format: text("format", { enum: ["xlsx", "pptx", "docx", "pdf", "png", "webp"] }).notNull(),
700
+ normalizedOptions: text("normalized_options").notNull(),
701
+ optionsHash: text("options_hash").generatedAlwaysAs(
702
+ sql`'sha256:' || encode(
703
+ opengeni_private.editable_artifact_text_sha256(normalized_options), 'hex'
704
+ )`,
705
+ ),
706
+ codecId: text("codec_id").notNull(),
707
+ codecVersion: text("codec_version").notNull(),
708
+ kernelVersion: text("kernel_version").notNull(),
709
+ fontRegistryHash: text("font_registry_hash").notNull(),
710
+ policyHash: text("policy_hash").notNull(),
711
+ state: text("state", { enum: ["pending", "running", "succeeded", "failed"] })
712
+ .notNull()
713
+ .default("pending"),
714
+ attemptCount: integer("attempt_count").notNull().default(0),
715
+ leaseOwner: text("lease_owner"),
716
+ leaseExpiresAt: timestamp("lease_expires_at", { withTimezone: true }),
717
+ settledByOwner: text("settled_by_owner"),
718
+ errorCode: text("error_code"),
719
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
720
+ startedAt: timestamp("started_at", { withTimezone: true }),
721
+ completedAt: timestamp("completed_at", { withTimezone: true }),
722
+ },
723
+ (table) => ({
724
+ pk: primaryKey({
725
+ name: "editable_artifact_materialization_jobs_pk",
726
+ columns: [table.accountId, table.workspaceId, table.artifactId, table.id],
727
+ }),
728
+ cache: uniqueIndex("editable_artifact_materialization_jobs_cache_uq").on(
729
+ table.accountId,
730
+ table.workspaceId,
731
+ table.artifactId,
732
+ table.inputSnapshotId,
733
+ table.stateHash,
734
+ table.format,
735
+ table.optionsHash,
736
+ table.codecId,
737
+ table.codecVersion,
738
+ table.kernelVersion,
739
+ table.fontRegistryHash,
740
+ table.policyHash,
741
+ ),
742
+ claim: index("editable_artifact_materialization_jobs_claim_idx")
743
+ .on(
744
+ sql`coalesce(${table.leaseExpiresAt}, ${table.createdAt})`,
745
+ table.createdAt,
746
+ table.accountId,
747
+ table.workspaceId,
748
+ table.artifactId,
749
+ table.id,
750
+ )
751
+ .where(sql`${table.state} in ('pending', 'running')`),
752
+ valid: check(
753
+ "editable_artifact_materialization_jobs_valid_chk",
754
+ sql`${stableIdSql(table.id)} and ${sha256Sql(table.stateHash)}
755
+ and ${sha256Sql(table.optionsHash)} and ${sha256Sql(table.fontRegistryHash)}
756
+ and ${sha256Sql(table.policyHash)} and ${stableIdSql(table.inputSnapshotId)}`,
757
+ ),
758
+ }),
759
+ );
760
+
761
+ export const editableArtifactMaterializationResults = pgTable(
762
+ "editable_artifact_materialization_results",
763
+ {
764
+ ...scopeColumns(),
765
+ artifactId: text("artifact_id").notNull(),
766
+ id: text("id").notNull(),
767
+ jobId: text("job_id").notNull(),
768
+ blobRefId: text("blob_ref_id").notNull(),
769
+ byteSize: bigint("byte_size", { mode: "number" }).notNull(),
770
+ contentHash: text("content_hash").notNull(),
771
+ mimeType: text("mime_type").notNull(),
772
+ verifiedAt: timestamp("verified_at", { withTimezone: true }).notNull(),
773
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
774
+ },
775
+ (table) => ({
776
+ pk: primaryKey({
777
+ name: "editable_artifact_materialization_results_pk",
778
+ columns: [table.accountId, table.workspaceId, table.artifactId, table.id],
779
+ }),
780
+ job: uniqueIndex("editable_artifact_materialization_results_job_uq").on(
781
+ table.accountId,
782
+ table.workspaceId,
783
+ table.artifactId,
784
+ table.jobId,
785
+ ),
786
+ valid: check(
787
+ "editable_artifact_materialization_results_valid_chk",
788
+ sql`${stableIdSql(table.id)} and ${sha256Sql(table.contentHash)}`,
789
+ ),
790
+ }),
791
+ );
792
+
793
+ export const editableArtifactLiveOutbox = pgTable(
794
+ "editable_artifact_live_outbox",
795
+ {
796
+ ...scopeColumns(),
797
+ artifactId: text("artifact_id").notNull(),
798
+ id: text("id").notNull(),
799
+ transactionId: text("transaction_id"),
800
+ snapshotId: text("snapshot_id"),
801
+ eventKind: text("event_kind", {
802
+ enum: ["transaction_committed", "snapshot_published"],
803
+ }).notNull(),
804
+ event: jsonb("event").$type<EditableArtifactOutboxEventRow>().notNull(),
805
+ state: text("state", {
806
+ enum: ["pending", "publishing", "published", "dead_lettered"],
807
+ })
808
+ .notNull()
809
+ .default("pending"),
810
+ attemptCount: integer("attempt_count").notNull().default(0),
811
+ leaseOwner: text("lease_owner"),
812
+ leaseExpiresAt: timestamp("lease_expires_at", { withTimezone: true }),
813
+ nextAttemptAt: timestamp("next_attempt_at", { withTimezone: true }).notNull().defaultNow(),
814
+ lastErrorCode: text("last_error_code"),
815
+ publishedAt: timestamp("published_at", { withTimezone: true }),
816
+ deadLetteredAt: timestamp("dead_lettered_at", { withTimezone: true }),
817
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
818
+ },
819
+ (table) => ({
820
+ pk: primaryKey({
821
+ name: "editable_artifact_live_outbox_pk",
822
+ columns: [table.accountId, table.workspaceId, table.artifactId, table.id],
823
+ }),
824
+ globalId: uniqueIndex("editable_artifact_live_outbox_id_uq").on(table.id),
825
+ transaction: uniqueIndex("editable_artifact_live_outbox_transaction_uq")
826
+ .on(table.accountId, table.workspaceId, table.artifactId, table.transactionId)
827
+ .where(sql`${table.eventKind} = 'transaction_committed'`),
828
+ snapshot: uniqueIndex("editable_artifact_live_outbox_snapshot_uq")
829
+ .on(table.accountId, table.workspaceId, table.artifactId, table.snapshotId)
830
+ .where(sql`${table.eventKind} = 'snapshot_published'`),
831
+ pendingClaim: index("editable_artifact_live_outbox_pending_claim_idx")
832
+ .on(table.nextAttemptAt, table.createdAt, table.id)
833
+ .where(sql`${table.state} = 'pending'`),
834
+ publishingClaim: index("editable_artifact_live_outbox_publishing_claim_idx")
835
+ .on(table.leaseExpiresAt, table.createdAt, table.id)
836
+ .where(sql`${table.state} = 'publishing'`),
837
+ valid: check("editable_artifact_live_outbox_id_chk", stableIdSql(table.id)),
838
+ }),
839
+ );
840
+
841
+ export const editableArtifactReplicaLeases = pgTable(
842
+ "editable_artifact_replica_leases",
843
+ {
844
+ ...scopeColumns(),
845
+ artifactId: text("artifact_id").notNull(),
846
+ modality: text("modality", {
847
+ enum: ["spreadsheet", "presentation", "document"],
848
+ }).notNull(),
849
+ replicaId: text("replica_id").notNull(),
850
+ actorKey: text("actor_key").notNull(),
851
+ appliedHeadSequence: bigint("applied_head_sequence", { mode: "number" }).notNull(),
852
+ causalFrontier: jsonb("causal_frontier").$type<EditableArtifactCausalFrontierRow>(),
853
+ nativeRevision: bigint("native_revision", { mode: "number" }),
854
+ leaseExpiresAt: timestamp("lease_expires_at", { withTimezone: true }).notNull(),
855
+ lastSeenAt: timestamp("last_seen_at", { withTimezone: true }).notNull().defaultNow(),
856
+ revokedAt: timestamp("revoked_at", { withTimezone: true }),
857
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
858
+ },
859
+ (table) => ({
860
+ pk: primaryKey({
861
+ name: "editable_artifact_replica_leases_pk",
862
+ columns: [table.accountId, table.workspaceId, table.artifactId, table.replicaId],
863
+ }),
864
+ expiry: index("editable_artifact_replica_leases_expiry_idx")
865
+ .on(table.leaseExpiresAt, table.replicaId)
866
+ .where(sql`${table.revokedAt} is null`),
867
+ replicaValid: check(
868
+ "editable_artifact_replica_leases_replica_chk",
869
+ sql`${replicaIdSql(table.replicaId)} and (
870
+ (${table.modality} = 'spreadsheet'
871
+ and jsonb_typeof(${table.causalFrontier}) = 'array'
872
+ and ${table.nativeRevision} is null)
873
+ or (${table.modality} in ('document', 'presentation')
874
+ and ${table.causalFrontier} is null
875
+ and ${table.nativeRevision} between 0 and 9007199254740991)
876
+ )`,
877
+ ),
878
+ }),
879
+ );