@sixb/pg 0.1.1 → 0.1.2
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/README.md +7 -6
- package/dist/agents/agent-storage.d.ts +2 -1
- package/dist/agents/agent-storage.d.ts.map +1 -1
- package/dist/agents/rows.d.ts +4 -11
- package/dist/agents/rows.d.ts.map +1 -1
- package/dist/agents/runs.d.ts +3 -2
- package/dist/agents/runs.d.ts.map +1 -1
- package/dist/auth-storage/service-accounts.d.ts.map +1 -1
- package/dist/auth-storage/shared.d.ts +0 -4
- package/dist/auth-storage/shared.d.ts.map +1 -1
- package/dist/connector-connection-storage.d.ts +9 -0
- package/dist/connector-connection-storage.d.ts.map +1 -0
- package/dist/index.d.ts +8 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3086 -730
- package/dist/index.js.map +28 -25
- package/dist/latest-run-query.d.ts.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/ontology-storage/materialization-session.d.ts.map +1 -1
- package/dist/ontology-storage/materialization-state.d.ts +0 -2
- package/dist/ontology-storage/materialization-state.d.ts.map +1 -1
- package/dist/ontology-storage/materialization-writer.d.ts.map +1 -1
- package/dist/ontology-storage/materializations.d.ts.map +1 -1
- package/dist/ontology-storage/outbox.d.ts.map +1 -1
- package/dist/ontology-storage/shared.d.ts +3 -6
- package/dist/ontology-storage/shared.d.ts.map +1 -1
- package/dist/pg-action-run-storage.d.ts +3 -2
- package/dist/pg-action-run-storage.d.ts.map +1 -1
- package/dist/pg-ai-usage-storage.d.ts +16 -0
- package/dist/pg-ai-usage-storage.d.ts.map +1 -0
- package/dist/pg-execution-storage.d.ts +14 -0
- package/dist/pg-execution-storage.d.ts.map +1 -0
- package/dist/pg-pipeline-run-storage.d.ts +5 -2
- package/dist/pg-pipeline-run-storage.d.ts.map +1 -1
- package/dist/pg-projection-run-storage.d.ts +5 -2
- package/dist/pg-projection-run-storage.d.ts.map +1 -1
- package/dist/pg-sync-run-storage.d.ts +5 -2
- package/dist/pg-sync-run-storage.d.ts.map +1 -1
- package/dist/pg-webhook-run-storage.d.ts +5 -2
- package/dist/pg-webhook-run-storage.d.ts.map +1 -1
- package/dist/pg-workflow-run-storage.d.ts +5 -3
- package/dist/pg-workflow-run-storage.d.ts.map +1 -1
- package/dist/run-list-query.d.ts +1 -1
- package/dist/run-list-query.d.ts.map +1 -1
- package/dist/testing.d.ts +6 -0
- package/dist/testing.d.ts.map +1 -0
- package/package.json +3 -3
- package/src/agents/agent-storage.ts +3 -2
- package/src/agents/rows.ts +12 -43
- package/src/agents/runs.ts +29 -15
- package/src/auth-storage/service-accounts.ts +14 -15
- package/src/auth-storage/shared.ts +0 -8
- package/src/connector-connection-storage.ts +760 -0
- package/src/index.ts +32 -15
- package/src/latest-run-query.ts +7 -1
- package/src/migrations/004-executions.sql +140 -0
- package/src/migrations/005-workflow-executions.sql +10 -0
- package/src/migrations/006-narrow-ontology-source-root-index.sql +4 -0
- package/src/migrations/007-split-overrides.sql +153 -0
- package/src/migrations/008-action-executions.sql +7 -0
- package/src/migrations/009-agent-executions.sql +21 -0
- package/src/migrations/010-ai-usage-accounting-foundation.sql +76 -0
- package/src/migrations/011-sync-failure-record.sql +23 -0
- package/src/migrations/012-pipeline-failure-record.sql +47 -0
- package/src/migrations/013-workflow-failure-record.sql +45 -0
- package/src/migrations/014-agent-failure-record.sql +56 -0
- package/src/migrations/015-projection-failure-record.sql +20 -0
- package/src/migrations/016-webhook-run-failure-record.sql +19 -0
- package/src/migrations/017-action-failure-record.sql +65 -0
- package/src/migrations/018-ontology-outbox-failure-record.sql +29 -0
- package/src/migrations/019-webhook-delivery-failure-record.sql +27 -0
- package/src/migrations/020-drop-run-usage-projections.sql +8 -0
- package/src/migrations/021-sync-pipeline-executions.sql +50 -0
- package/src/migrations/022-projection-executions.sql +115 -0
- package/src/migrations/023-webhook-executions.sql +30 -0
- package/src/migrations/024-ontology-commit-executions.sql +12 -0
- package/src/migrations/025-connector-connections.sql +231 -0
- package/src/migrations.ts +72 -0
- package/src/ontology-storage/materialization-session.ts +25 -28
- package/src/ontology-storage/materialization-state.ts +159 -43
- package/src/ontology-storage/materialization-writer.ts +146 -75
- package/src/ontology-storage/materializations.ts +3 -1
- package/src/ontology-storage/outbox.ts +9 -2
- package/src/ontology-storage/shared.ts +10 -20
- package/src/pg-action-run-storage.ts +43 -67
- package/src/pg-ai-usage-storage.ts +290 -0
- package/src/pg-execution-storage.ts +147 -0
- package/src/pg-pipeline-run-storage.ts +107 -41
- package/src/pg-projection-run-storage.ts +159 -91
- package/src/pg-sync-run-storage.ts +100 -28
- package/src/pg-webhook-run-storage.ts +89 -57
- package/src/pg-workflow-run-storage.ts +97 -130
- package/src/run-list-query.ts +9 -4
- package/src/testing.ts +18 -0
- package/dist/pg-webhook-delivery-storage.d.ts +0 -17
- package/dist/pg-webhook-delivery-storage.d.ts.map +0 -1
- package/src/pg-webhook-delivery-storage.ts +0 -180
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
ALTER TABLE workflow_runs RENAME COLUMN error TO legacy_error;
|
|
2
|
+
ALTER TABLE workflow_runs ADD COLUMN error JSONB;
|
|
3
|
+
|
|
4
|
+
UPDATE workflow_runs
|
|
5
|
+
SET error = jsonb_build_object(
|
|
6
|
+
'code', CASE WHEN status = 'cancelled' THEN 'runtime.cancelled' ELSE 'internal.unexpected' END,
|
|
7
|
+
'message', CASE
|
|
8
|
+
WHEN status = 'cancelled' THEN 'Execution was cancelled.'
|
|
9
|
+
ELSE 'An unexpected internal error occurred.'
|
|
10
|
+
END,
|
|
11
|
+
'retryable', false,
|
|
12
|
+
'at', to_char(COALESCE(finished_at, started_at) AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'),
|
|
13
|
+
'details', jsonb_build_object(
|
|
14
|
+
'workflowId', workflow_id,
|
|
15
|
+
'workflowRunId', id,
|
|
16
|
+
'migratedFromLegacyError', true
|
|
17
|
+
)
|
|
18
|
+
)
|
|
19
|
+
WHERE legacy_error IS NOT NULL;
|
|
20
|
+
|
|
21
|
+
ALTER TABLE workflow_runs DROP COLUMN legacy_error;
|
|
22
|
+
|
|
23
|
+
ALTER TABLE workflow_node_runs RENAME COLUMN error TO legacy_error;
|
|
24
|
+
ALTER TABLE workflow_node_runs ADD COLUMN error JSONB;
|
|
25
|
+
|
|
26
|
+
UPDATE workflow_node_runs
|
|
27
|
+
SET error = jsonb_build_object(
|
|
28
|
+
'code', CASE WHEN status = 'cancelled' THEN 'runtime.cancelled' ELSE 'internal.unexpected' END,
|
|
29
|
+
'message', CASE
|
|
30
|
+
WHEN status = 'cancelled' THEN 'Execution was cancelled.'
|
|
31
|
+
ELSE 'An unexpected internal error occurred.'
|
|
32
|
+
END,
|
|
33
|
+
'retryable', false,
|
|
34
|
+
'at', to_char(COALESCE(finished_at, started_at) AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'),
|
|
35
|
+
'details', jsonb_build_object(
|
|
36
|
+
'workflowId', workflow_id,
|
|
37
|
+
'workflowRunId', workflow_run_id,
|
|
38
|
+
'nodeId', node_id,
|
|
39
|
+
'nodeRunId', id,
|
|
40
|
+
'migratedFromLegacyError', true
|
|
41
|
+
)
|
|
42
|
+
)
|
|
43
|
+
WHERE legacy_error IS NOT NULL;
|
|
44
|
+
|
|
45
|
+
ALTER TABLE workflow_node_runs DROP COLUMN legacy_error;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
ALTER TABLE agent_runs RENAME COLUMN error TO legacy_error;
|
|
2
|
+
ALTER TABLE agent_runs ADD COLUMN error JSONB;
|
|
3
|
+
|
|
4
|
+
UPDATE agent_runs
|
|
5
|
+
SET error = jsonb_build_object(
|
|
6
|
+
'code', CASE WHEN status = 'cancelled' THEN 'runtime.cancelled' ELSE 'internal.unexpected' END,
|
|
7
|
+
'message', CASE
|
|
8
|
+
WHEN status = 'cancelled' THEN 'Execution was cancelled.'
|
|
9
|
+
ELSE 'An unexpected internal error occurred.'
|
|
10
|
+
END,
|
|
11
|
+
'retryable', false,
|
|
12
|
+
'at', to_char(COALESCE(completed_at, started_at, created_at) AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'),
|
|
13
|
+
'details', jsonb_build_object(
|
|
14
|
+
'agentId', agent_id,
|
|
15
|
+
'runId', id,
|
|
16
|
+
'threadId', thread_id,
|
|
17
|
+
'migratedFromLegacyError', true
|
|
18
|
+
)
|
|
19
|
+
)
|
|
20
|
+
WHERE legacy_error IS NOT NULL;
|
|
21
|
+
|
|
22
|
+
ALTER TABLE agent_runs DROP COLUMN legacy_error;
|
|
23
|
+
|
|
24
|
+
ALTER TABLE workflow_agent_node_runs RENAME COLUMN error TO legacy_error;
|
|
25
|
+
ALTER TABLE workflow_agent_node_runs ADD COLUMN error JSONB;
|
|
26
|
+
|
|
27
|
+
UPDATE workflow_agent_node_runs AS agent_node
|
|
28
|
+
SET error = jsonb_build_object(
|
|
29
|
+
'code', CASE
|
|
30
|
+
WHEN agent_node.status = 'cancelled' THEN 'runtime.cancelled'
|
|
31
|
+
ELSE 'internal.unexpected'
|
|
32
|
+
END,
|
|
33
|
+
'message', CASE
|
|
34
|
+
WHEN agent_node.status = 'cancelled' THEN 'Execution was cancelled.'
|
|
35
|
+
ELSE 'An unexpected internal error occurred.'
|
|
36
|
+
END,
|
|
37
|
+
'retryable', false,
|
|
38
|
+
'at', to_char(
|
|
39
|
+
COALESCE(agent_node.completed_at, agent_node.started_at, agent_node.created_at) AT TIME ZONE 'UTC',
|
|
40
|
+
'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'
|
|
41
|
+
),
|
|
42
|
+
'details', jsonb_build_object(
|
|
43
|
+
'agentId', agent_node.agent_id,
|
|
44
|
+
'workflowId', node.workflow_id,
|
|
45
|
+
'workflowRunId', node.workflow_run_id,
|
|
46
|
+
'nodeId', node.node_id,
|
|
47
|
+
'nodeRunId', agent_node.node_run_id,
|
|
48
|
+
'migratedFromLegacyError', true
|
|
49
|
+
)
|
|
50
|
+
)
|
|
51
|
+
FROM workflow_node_runs AS node
|
|
52
|
+
WHERE node.project_id = agent_node.project_id
|
|
53
|
+
AND node.id = agent_node.node_run_id
|
|
54
|
+
AND agent_node.legacy_error IS NOT NULL;
|
|
55
|
+
|
|
56
|
+
ALTER TABLE workflow_agent_node_runs DROP COLUMN legacy_error;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
ALTER TABLE projection_runs ADD COLUMN error JSONB;
|
|
2
|
+
|
|
3
|
+
UPDATE projection_runs
|
|
4
|
+
SET error = jsonb_build_object(
|
|
5
|
+
'code', CASE WHEN status = 'cancelled' THEN 'runtime.cancelled' ELSE 'internal.unexpected' END,
|
|
6
|
+
'message', CASE
|
|
7
|
+
WHEN status = 'cancelled' THEN 'Execution was cancelled.'
|
|
8
|
+
ELSE 'An unexpected internal error occurred.'
|
|
9
|
+
END,
|
|
10
|
+
'retryable', false,
|
|
11
|
+
'at', to_char(COALESCE(finished_at, started_at) AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'),
|
|
12
|
+
'details', jsonb_build_object(
|
|
13
|
+
'projectionId', projection_id,
|
|
14
|
+
'runId', id,
|
|
15
|
+
'migratedFromLegacyError', true
|
|
16
|
+
)
|
|
17
|
+
)
|
|
18
|
+
WHERE error_message IS NOT NULL;
|
|
19
|
+
|
|
20
|
+
ALTER TABLE projection_runs DROP COLUMN error_message;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
ALTER TABLE webhook_runs RENAME COLUMN error TO legacy_error;
|
|
2
|
+
ALTER TABLE webhook_runs ADD COLUMN error JSONB;
|
|
3
|
+
|
|
4
|
+
UPDATE webhook_runs
|
|
5
|
+
SET error = jsonb_build_object(
|
|
6
|
+
'code', 'internal.unexpected',
|
|
7
|
+
'message', 'An unexpected internal error occurred.',
|
|
8
|
+
'retryable', false,
|
|
9
|
+
'at', to_char(COALESCE(finished_at, started_at) AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'),
|
|
10
|
+
'details', jsonb_build_object(
|
|
11
|
+
'connectorId', connector_id,
|
|
12
|
+
'webhookId', webhook_id,
|
|
13
|
+
'runId', id,
|
|
14
|
+
'migratedFromLegacyError', true
|
|
15
|
+
)
|
|
16
|
+
)
|
|
17
|
+
WHERE legacy_error IS NOT NULL;
|
|
18
|
+
|
|
19
|
+
ALTER TABLE webhook_runs DROP COLUMN legacy_error;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
ALTER TABLE action_runs
|
|
2
|
+
ADD COLUMN writeback_error JSONB,
|
|
3
|
+
ADD COLUMN effects_error JSONB,
|
|
4
|
+
ADD COLUMN error JSONB;
|
|
5
|
+
|
|
6
|
+
UPDATE action_runs
|
|
7
|
+
SET writeback_error = jsonb_build_object(
|
|
8
|
+
'code', 'internal.unexpected',
|
|
9
|
+
'message', 'An unexpected internal error occurred.',
|
|
10
|
+
'retryable', false,
|
|
11
|
+
'at', to_char(COALESCE(writeback_completed_at, finished_at, queued_at) AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'),
|
|
12
|
+
'details', jsonb_build_object(
|
|
13
|
+
'actionId', action_id,
|
|
14
|
+
'runId', id,
|
|
15
|
+
'phase', 'writeback'
|
|
16
|
+
)
|
|
17
|
+
)
|
|
18
|
+
WHERE writeback_error_name IS NOT NULL OR writeback_error_message IS NOT NULL;
|
|
19
|
+
|
|
20
|
+
UPDATE action_runs
|
|
21
|
+
SET effects_error = jsonb_build_object(
|
|
22
|
+
'code', 'internal.unexpected',
|
|
23
|
+
'message', 'An unexpected internal error occurred.',
|
|
24
|
+
'retryable', false,
|
|
25
|
+
'at', to_char(COALESCE(effects_completed_at, finished_at, queued_at) AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'),
|
|
26
|
+
'details', jsonb_build_object(
|
|
27
|
+
'actionId', action_id,
|
|
28
|
+
'runId', id,
|
|
29
|
+
'phase', 'effects'
|
|
30
|
+
)
|
|
31
|
+
)
|
|
32
|
+
WHERE effects_error_name IS NOT NULL OR effects_error_message IS NOT NULL;
|
|
33
|
+
|
|
34
|
+
UPDATE action_runs
|
|
35
|
+
SET error = jsonb_build_object(
|
|
36
|
+
'code', CASE
|
|
37
|
+
WHEN error_phase = 'enqueue' THEN 'queue.enqueue_failed'
|
|
38
|
+
WHEN error_phase = 'cancelled' OR status = 'cancelled' THEN 'runtime.cancelled'
|
|
39
|
+
ELSE 'internal.unexpected'
|
|
40
|
+
END,
|
|
41
|
+
'message', CASE
|
|
42
|
+
WHEN error_phase = 'enqueue' THEN 'The job could not be enqueued.'
|
|
43
|
+
WHEN error_phase = 'cancelled' OR status = 'cancelled' THEN 'Execution was cancelled.'
|
|
44
|
+
ELSE 'An unexpected internal error occurred.'
|
|
45
|
+
END,
|
|
46
|
+
'retryable', COALESCE(error_phase = 'enqueue', false),
|
|
47
|
+
'at', to_char(COALESCE(finished_at, queued_at) AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'),
|
|
48
|
+
'details', jsonb_build_object(
|
|
49
|
+
'actionId', action_id,
|
|
50
|
+
'runId', id,
|
|
51
|
+
'phase', COALESCE(error_phase, phase, 'request')
|
|
52
|
+
)
|
|
53
|
+
)
|
|
54
|
+
WHERE error_name IS NOT NULL OR error_message IS NOT NULL;
|
|
55
|
+
|
|
56
|
+
ALTER TABLE action_runs
|
|
57
|
+
DROP COLUMN writeback_error_name,
|
|
58
|
+
DROP COLUMN writeback_error_message,
|
|
59
|
+
DROP COLUMN writeback_error_phase,
|
|
60
|
+
DROP COLUMN effects_error_name,
|
|
61
|
+
DROP COLUMN effects_error_message,
|
|
62
|
+
DROP COLUMN effects_error_phase,
|
|
63
|
+
DROP COLUMN error_name,
|
|
64
|
+
DROP COLUMN error_message,
|
|
65
|
+
DROP COLUMN error_phase;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
-- The legacy record has no failure timestamp. Use its next availability time as the closest
|
|
2
|
+
-- durable timestamp and mark that approximation explicitly in details.
|
|
3
|
+
ALTER TABLE ontology_outbox RENAME COLUMN last_error TO last_failure;
|
|
4
|
+
|
|
5
|
+
ALTER TABLE ontology_outbox
|
|
6
|
+
ALTER COLUMN last_failure TYPE JSONB
|
|
7
|
+
USING (
|
|
8
|
+
CASE
|
|
9
|
+
WHEN last_failure IS NULL
|
|
10
|
+
OR last_failure = 'Outbox dispatcher stopped before publication completed.'
|
|
11
|
+
THEN NULL
|
|
12
|
+
ELSE jsonb_build_object(
|
|
13
|
+
'code', 'event.delivery_failed',
|
|
14
|
+
'message', 'Event delivery failed.',
|
|
15
|
+
'retryable', true,
|
|
16
|
+
'at', to_char(
|
|
17
|
+
available_at AT TIME ZONE 'UTC',
|
|
18
|
+
'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'
|
|
19
|
+
),
|
|
20
|
+
'details', jsonb_build_object(
|
|
21
|
+
'attempts', attempts,
|
|
22
|
+
'eventIds', jsonb_build_array(id),
|
|
23
|
+
'eventTypes', jsonb_build_array(envelope->>'type'),
|
|
24
|
+
'migratedFromLegacyLastError', true,
|
|
25
|
+
'timestampSource', 'availableAt'
|
|
26
|
+
)
|
|
27
|
+
)
|
|
28
|
+
END
|
|
29
|
+
);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
-- Legacy deliveries normally have an exact failure timestamp. Fall back to the receipt timestamp
|
|
2
|
+
-- only for inconsistent historical rows and record the source so the approximation stays visible.
|
|
3
|
+
ALTER TABLE webhook_deliveries RENAME COLUMN error TO failure;
|
|
4
|
+
|
|
5
|
+
ALTER TABLE webhook_deliveries
|
|
6
|
+
ALTER COLUMN failure TYPE JSONB
|
|
7
|
+
USING (
|
|
8
|
+
CASE
|
|
9
|
+
WHEN failure IS NULL THEN NULL
|
|
10
|
+
ELSE jsonb_build_object(
|
|
11
|
+
'code', 'webhook.delivery_failed',
|
|
12
|
+
'message', 'Webhook delivery failed.',
|
|
13
|
+
'retryable', true,
|
|
14
|
+
'at', to_char(
|
|
15
|
+
COALESCE(failed_at, received_at) AT TIME ZONE 'UTC',
|
|
16
|
+
'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'
|
|
17
|
+
),
|
|
18
|
+
'details', jsonb_build_object(
|
|
19
|
+
'connectorId', connector_id,
|
|
20
|
+
'webhookId', webhook_id,
|
|
21
|
+
'idempotencyKey', idempotency_key,
|
|
22
|
+
'migratedFromLegacyError', true,
|
|
23
|
+
'timestampSource', CASE WHEN failed_at IS NULL THEN 'receivedAt' ELSE 'failedAt' END
|
|
24
|
+
)
|
|
25
|
+
)
|
|
26
|
+
END
|
|
27
|
+
);
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
ALTER TABLE sync_runs
|
|
2
|
+
DROP CONSTRAINT sync_runs_status_check,
|
|
3
|
+
ADD COLUMN execution_id TEXT NOT NULL,
|
|
4
|
+
ADD COLUMN queued_at TIMESTAMPTZ NOT NULL,
|
|
5
|
+
ALTER COLUMN started_at DROP NOT NULL,
|
|
6
|
+
ADD CONSTRAINT sync_runs_status_check
|
|
7
|
+
CHECK (status IN ('queued', 'running', 'succeeded', 'failed', 'cancelled')),
|
|
8
|
+
ADD CONSTRAINT fk_sync_runs_execution
|
|
9
|
+
FOREIGN KEY (project_id, execution_id)
|
|
10
|
+
REFERENCES executions (project_id, id)
|
|
11
|
+
ON DELETE RESTRICT,
|
|
12
|
+
ADD CONSTRAINT uq_sync_runs_execution UNIQUE (project_id, execution_id);
|
|
13
|
+
|
|
14
|
+
DROP INDEX idx_sync_runs_project_started;
|
|
15
|
+
DROP INDEX idx_sync_runs_project_dataset_started;
|
|
16
|
+
DROP INDEX idx_sync_runs_project_sync_started;
|
|
17
|
+
DROP INDEX idx_sync_runs_project_status_started;
|
|
18
|
+
|
|
19
|
+
CREATE INDEX idx_sync_runs_project_started
|
|
20
|
+
ON sync_runs (project_id, COALESCE(started_at, queued_at) DESC);
|
|
21
|
+
CREATE INDEX idx_sync_runs_project_dataset_started
|
|
22
|
+
ON sync_runs (project_id, dataset_id, COALESCE(started_at, queued_at) DESC);
|
|
23
|
+
CREATE INDEX idx_sync_runs_project_sync_started
|
|
24
|
+
ON sync_runs (project_id, sync_id, COALESCE(started_at, queued_at) DESC);
|
|
25
|
+
CREATE INDEX idx_sync_runs_project_status_started
|
|
26
|
+
ON sync_runs (project_id, status, COALESCE(started_at, queued_at) DESC);
|
|
27
|
+
|
|
28
|
+
ALTER TABLE pipeline_runs
|
|
29
|
+
DROP CONSTRAINT pipeline_runs_status_check,
|
|
30
|
+
ADD COLUMN execution_id TEXT NOT NULL,
|
|
31
|
+
ADD COLUMN queued_at TIMESTAMPTZ NOT NULL,
|
|
32
|
+
ALTER COLUMN started_at DROP NOT NULL,
|
|
33
|
+
ADD CONSTRAINT pipeline_runs_status_check
|
|
34
|
+
CHECK (status IN ('queued', 'running', 'succeeded', 'failed', 'cancelled')),
|
|
35
|
+
ADD CONSTRAINT fk_pipeline_runs_execution
|
|
36
|
+
FOREIGN KEY (project_id, execution_id)
|
|
37
|
+
REFERENCES executions (project_id, id)
|
|
38
|
+
ON DELETE RESTRICT,
|
|
39
|
+
ADD CONSTRAINT uq_pipeline_runs_execution UNIQUE (project_id, execution_id);
|
|
40
|
+
|
|
41
|
+
DROP INDEX idx_pipeline_runs_project_started;
|
|
42
|
+
DROP INDEX idx_pipeline_runs_project_pipeline_started;
|
|
43
|
+
DROP INDEX idx_pipeline_runs_project_status_started;
|
|
44
|
+
|
|
45
|
+
CREATE INDEX idx_pipeline_runs_project_started
|
|
46
|
+
ON pipeline_runs (project_id, COALESCE(started_at, queued_at) DESC);
|
|
47
|
+
CREATE INDEX idx_pipeline_runs_project_pipeline_started
|
|
48
|
+
ON pipeline_runs (project_id, pipeline_id, COALESCE(started_at, queued_at) DESC);
|
|
49
|
+
CREATE INDEX idx_pipeline_runs_project_status_started
|
|
50
|
+
ON pipeline_runs (project_id, status, COALESCE(started_at, queued_at) DESC);
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
ALTER TABLE executions
|
|
2
|
+
DROP CONSTRAINT executions_source_kind_check,
|
|
3
|
+
ADD CONSTRAINT executions_source_kind_check CHECK (
|
|
4
|
+
source_kind IN ('http', 'webhook', 'schedule', 'event', 'datasetVersion', 'execution')
|
|
5
|
+
);
|
|
6
|
+
|
|
7
|
+
-- Existing Projection rows cannot be assigned honest authority. Refuse them explicitly before
|
|
8
|
+
-- rebuilding anything; this guard is migration-local and leaves no function or trigger behind.
|
|
9
|
+
CREATE TEMP TABLE projection_execution_migration_guard (
|
|
10
|
+
must_be_empty BOOLEAN NOT NULL CHECK (must_be_empty = FALSE)
|
|
11
|
+
) ON COMMIT DROP;
|
|
12
|
+
INSERT INTO projection_execution_migration_guard (must_be_empty)
|
|
13
|
+
SELECT TRUE FROM projection_runs LIMIT 1;
|
|
14
|
+
DROP TABLE projection_execution_migration_guard;
|
|
15
|
+
|
|
16
|
+
DROP TABLE projection_runs;
|
|
17
|
+
|
|
18
|
+
CREATE TABLE projection_runs (
|
|
19
|
+
project_id TEXT NOT NULL,
|
|
20
|
+
id TEXT NOT NULL,
|
|
21
|
+
execution_id TEXT NOT NULL,
|
|
22
|
+
projection_id TEXT NOT NULL,
|
|
23
|
+
projection_kind TEXT NOT NULL CHECK (projection_kind IN ('object', 'link', 'telemetry')),
|
|
24
|
+
materialization_protocol TEXT NOT NULL CHECK (
|
|
25
|
+
materialization_protocol IN ('replacement', 'telemetry')
|
|
26
|
+
),
|
|
27
|
+
dataset_id TEXT NOT NULL,
|
|
28
|
+
dataset_version_id TEXT NOT NULL,
|
|
29
|
+
dataset_version_created_at TEXT NOT NULL,
|
|
30
|
+
ontology_revision TEXT NOT NULL,
|
|
31
|
+
projection_revision TEXT NOT NULL,
|
|
32
|
+
ownership_hash TEXT NOT NULL,
|
|
33
|
+
object_type_id TEXT,
|
|
34
|
+
source_object_type_id TEXT,
|
|
35
|
+
target_object_type_id TEXT,
|
|
36
|
+
status TEXT NOT NULL CHECK (status IN ('queued', 'running', 'succeeded', 'failed', 'cancelled')),
|
|
37
|
+
queued_at TIMESTAMPTZ NOT NULL,
|
|
38
|
+
started_at TIMESTAMPTZ,
|
|
39
|
+
finished_at TIMESTAMPTZ,
|
|
40
|
+
attempt BIGINT NOT NULL CHECK (attempt >= 0),
|
|
41
|
+
execution_token TEXT,
|
|
42
|
+
fixed_batch_size BIGINT CHECK (fixed_batch_size IS NULL OR fixed_batch_size > 0),
|
|
43
|
+
next_batch_ordinal BIGINT CHECK (next_batch_ordinal IS NULL OR next_batch_ordinal >= 0),
|
|
44
|
+
next_row_offset BIGINT CHECK (next_row_offset IS NULL OR next_row_offset >= 0),
|
|
45
|
+
input_exhausted BOOLEAN,
|
|
46
|
+
missing_target_object_type_id TEXT,
|
|
47
|
+
missing_target_object_id TEXT,
|
|
48
|
+
missing_target_batch_ordinal BIGINT CHECK (
|
|
49
|
+
missing_target_batch_ordinal IS NULL OR missing_target_batch_ordinal >= 0
|
|
50
|
+
),
|
|
51
|
+
missing_target_first_seen_at TIMESTAMPTZ,
|
|
52
|
+
source_rows_read BIGINT NOT NULL DEFAULT 0 CHECK (source_rows_read >= 0),
|
|
53
|
+
source_rows_skipped BIGINT NOT NULL DEFAULT 0 CHECK (source_rows_skipped >= 0),
|
|
54
|
+
error JSONB,
|
|
55
|
+
PRIMARY KEY (project_id, id),
|
|
56
|
+
UNIQUE (project_id, execution_id),
|
|
57
|
+
FOREIGN KEY (project_id, execution_id)
|
|
58
|
+
REFERENCES executions (project_id, id)
|
|
59
|
+
ON DELETE RESTRICT,
|
|
60
|
+
CHECK (source_rows_skipped <= source_rows_read),
|
|
61
|
+
CHECK ((status = 'running') = (execution_token IS NOT NULL)),
|
|
62
|
+
CHECK (
|
|
63
|
+
(status = 'queued' AND attempt = 0 AND started_at IS NULL AND finished_at IS NULL
|
|
64
|
+
AND error IS NULL)
|
|
65
|
+
OR (status = 'running' AND attempt >= 1 AND started_at IS NOT NULL AND finished_at IS NULL
|
|
66
|
+
AND error IS NULL)
|
|
67
|
+
OR (
|
|
68
|
+
status IN ('succeeded', 'failed', 'cancelled')
|
|
69
|
+
AND finished_at IS NOT NULL
|
|
70
|
+
AND (
|
|
71
|
+
(error->>'code' = 'queue.enqueue_failed'
|
|
72
|
+
AND status = 'failed' AND attempt = 0 AND started_at IS NULL)
|
|
73
|
+
OR (COALESCE(error->>'code', '') != 'queue.enqueue_failed'
|
|
74
|
+
AND attempt >= 1 AND started_at IS NOT NULL)
|
|
75
|
+
)
|
|
76
|
+
)
|
|
77
|
+
),
|
|
78
|
+
CHECK (status != 'succeeded' OR error IS NULL),
|
|
79
|
+
CHECK ((projection_kind = 'telemetry') = (materialization_protocol = 'telemetry')),
|
|
80
|
+
CHECK (
|
|
81
|
+
(projection_kind = 'link' AND object_type_id IS NULL
|
|
82
|
+
AND source_object_type_id IS NOT NULL AND target_object_type_id IS NOT NULL)
|
|
83
|
+
OR (projection_kind IN ('object', 'telemetry') AND object_type_id IS NOT NULL
|
|
84
|
+
AND source_object_type_id IS NULL AND target_object_type_id IS NULL)
|
|
85
|
+
),
|
|
86
|
+
CHECK (
|
|
87
|
+
(materialization_protocol = 'replacement' AND fixed_batch_size IS NULL
|
|
88
|
+
AND next_batch_ordinal IS NULL AND next_row_offset IS NULL AND input_exhausted IS NULL)
|
|
89
|
+
OR (materialization_protocol = 'telemetry' AND fixed_batch_size IS NOT NULL
|
|
90
|
+
AND next_batch_ordinal IS NOT NULL AND next_row_offset IS NOT NULL
|
|
91
|
+
AND input_exhausted IS NOT NULL)
|
|
92
|
+
),
|
|
93
|
+
CHECK (
|
|
94
|
+
(missing_target_object_type_id IS NULL AND missing_target_object_id IS NULL
|
|
95
|
+
AND missing_target_batch_ordinal IS NULL AND missing_target_first_seen_at IS NULL)
|
|
96
|
+
OR (projection_kind = 'telemetry' AND missing_target_object_type_id = object_type_id
|
|
97
|
+
AND missing_target_object_id IS NOT NULL
|
|
98
|
+
AND missing_target_batch_ordinal = next_batch_ordinal
|
|
99
|
+
AND missing_target_first_seen_at IS NOT NULL)
|
|
100
|
+
),
|
|
101
|
+
CHECK (projection_kind != 'telemetry' OR status != 'succeeded' OR input_exhausted = TRUE)
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
CREATE INDEX idx_projection_runs_project_started
|
|
105
|
+
ON projection_runs (project_id, COALESCE(started_at, queued_at) DESC);
|
|
106
|
+
CREATE INDEX idx_projection_runs_project_projection_started
|
|
107
|
+
ON projection_runs (project_id, projection_id, COALESCE(started_at, queued_at) DESC);
|
|
108
|
+
CREATE INDEX idx_projection_runs_project_dataset_started
|
|
109
|
+
ON projection_runs (project_id, dataset_id, COALESCE(started_at, queued_at) DESC);
|
|
110
|
+
CREATE INDEX idx_projection_runs_project_version_started
|
|
111
|
+
ON projection_runs (project_id, dataset_version_id, COALESCE(started_at, queued_at) DESC);
|
|
112
|
+
CREATE INDEX idx_projection_runs_project_status_started
|
|
113
|
+
ON projection_runs (project_id, status, COALESCE(started_at, queued_at) DESC);
|
|
114
|
+
CREATE INDEX idx_projection_runs_project_object_type_started
|
|
115
|
+
ON projection_runs (project_id, object_type_id, COALESCE(started_at, queued_at) DESC);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
-- Existing Webhook runs and delivery claims cannot be assigned honest authority retroactively.
|
|
2
|
+
-- Fail before changing the schema instead of inventing execution provenance or discarding claims.
|
|
3
|
+
SELECT 1 / CASE
|
|
4
|
+
WHEN EXISTS (SELECT 1 FROM webhook_runs) OR EXISTS (SELECT 1 FROM webhook_deliveries)
|
|
5
|
+
THEN 0
|
|
6
|
+
ELSE 1
|
|
7
|
+
END;
|
|
8
|
+
|
|
9
|
+
ALTER TABLE webhook_runs
|
|
10
|
+
DROP CONSTRAINT webhook_runs_status_check,
|
|
11
|
+
ADD COLUMN execution_id TEXT NOT NULL,
|
|
12
|
+
ADD COLUMN request_body_sha256 TEXT NOT NULL CHECK (length(request_body_sha256) = 64),
|
|
13
|
+
ALTER COLUMN request_body_bytes SET NOT NULL,
|
|
14
|
+
DROP COLUMN delivery_claim_result,
|
|
15
|
+
ADD CONSTRAINT webhook_runs_status_check
|
|
16
|
+
CHECK (status IN ('running', 'succeeded', 'failed')),
|
|
17
|
+
ADD CONSTRAINT webhook_runs_lifecycle_check CHECK (
|
|
18
|
+
(status = 'running' AND finished_at IS NULL AND response_status IS NULL AND error IS NULL)
|
|
19
|
+
OR (status = 'succeeded' AND finished_at IS NOT NULL AND error IS NULL)
|
|
20
|
+
OR (status = 'failed' AND finished_at IS NOT NULL AND error IS NOT NULL)
|
|
21
|
+
),
|
|
22
|
+
ADD CONSTRAINT fk_webhook_runs_execution
|
|
23
|
+
FOREIGN KEY (project_id, execution_id)
|
|
24
|
+
REFERENCES executions (project_id, id)
|
|
25
|
+
ON DELETE RESTRICT,
|
|
26
|
+
ADD CONSTRAINT uq_webhook_runs_execution UNIQUE (project_id, execution_id),
|
|
27
|
+
ADD CONSTRAINT uq_webhook_runs_delivery
|
|
28
|
+
UNIQUE (project_id, connector_id, webhook_id, idempotency_key);
|
|
29
|
+
|
|
30
|
+
DROP TABLE webhook_deliveries;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
-- Existing commits cannot be assigned honest execution authority retroactively.
|
|
2
|
+
SELECT 1 / CASE WHEN EXISTS (SELECT 1 FROM ontology_commits) THEN 0 ELSE 1 END;
|
|
3
|
+
|
|
4
|
+
ALTER TABLE ontology_commits
|
|
5
|
+
ADD COLUMN execution_id TEXT NOT NULL,
|
|
6
|
+
ADD CONSTRAINT fk_ontology_commits_execution
|
|
7
|
+
FOREIGN KEY (project_id, execution_id)
|
|
8
|
+
REFERENCES executions (project_id, id)
|
|
9
|
+
ON DELETE RESTRICT;
|
|
10
|
+
|
|
11
|
+
CREATE INDEX idx_ontology_commits_execution
|
|
12
|
+
ON ontology_commits (project_id, execution_id);
|