@secondlayer/shared 6.3.4 → 6.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/crypto/secrets.js +2 -5
- package/dist/src/crypto/secrets.js.map +3 -3
- package/dist/src/db/index.d.ts +6 -1
- package/dist/src/db/queries/account-spend-caps.d.ts +5 -0
- package/dist/src/db/queries/account-usage.d.ts +5 -0
- package/dist/src/db/queries/accounts.d.ts +5 -0
- package/dist/src/db/queries/chain-reorgs.d.ts +5 -0
- package/dist/src/db/queries/integrity.d.ts +5 -0
- package/dist/src/db/queries/projects.d.ts +5 -0
- package/dist/src/db/queries/provisioning-audit.d.ts +5 -0
- package/dist/src/db/queries/subgraph-gaps.d.ts +5 -0
- package/dist/src/db/queries/subgraph-operations.d.ts +5 -0
- package/dist/src/db/queries/subgraphs.d.ts +5 -0
- package/dist/src/db/queries/subscriptions.d.ts +5 -0
- package/dist/src/db/queries/subscriptions.js +2 -5
- package/dist/src/db/queries/subscriptions.js.map +3 -3
- package/dist/src/db/queries/tenant-compute-addons.d.ts +5 -0
- package/dist/src/db/queries/usage.d.ts +5 -0
- package/dist/src/db/schema.d.ts +6 -1
- package/dist/src/index.d.ts +6 -1
- package/dist/src/mode.d.ts +6 -12
- package/dist/src/mode.js +2 -6
- package/dist/src/mode.js.map +3 -3
- package/dist/src/node/local-client.d.ts +5 -0
- package/migrations/0074_service_heartbeats.ts +23 -0
- package/migrations/0075_restore_subgraphs_on_platform.ts +166 -0
- package/migrations/0076_deprecate_tenants.ts +19 -0
- package/package.json +1 -1
- package/dist/src/db/queries/tenants.d.ts +0 -795
- package/dist/src/db/queries/tenants.js +0 -308
- package/dist/src/db/queries/tenants.js.map +0 -12
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { type Kysely, sql } from "kysely";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Restore `subgraphs` + `subgraph_operations` on platform DBs that lost them
|
|
5
|
+
* during the shared→dedicated cutover (manual drop after 0041; see note in
|
|
6
|
+
* 0045). After the 2026-05-14 shared-rip pivot, the platform subgraph-processor
|
|
7
|
+
* crashes with `relation "subgraphs" does not exist` because no migration ever
|
|
8
|
+
* recreated the parent table — only the satellite tables (gaps, stats,
|
|
9
|
+
* snapshots, usage_daily) survived.
|
|
10
|
+
*
|
|
11
|
+
* Idempotent: each step is guarded so this is a no-op on DBs that already have
|
|
12
|
+
* the tables (OSS, fresh dev, or any tenant DB).
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
async function tableExists(
|
|
16
|
+
db: Kysely<unknown>,
|
|
17
|
+
tableName: string,
|
|
18
|
+
): Promise<boolean> {
|
|
19
|
+
const { rows } = await sql<{ exists: boolean }>`
|
|
20
|
+
SELECT to_regclass(${`public.${tableName}`}) IS NOT NULL AS exists
|
|
21
|
+
`.execute(db);
|
|
22
|
+
return rows[0]?.exists === true;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
26
|
+
if (!(await tableExists(db, "subgraphs"))) {
|
|
27
|
+
await sql`
|
|
28
|
+
CREATE TABLE subgraphs (
|
|
29
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
30
|
+
name text NOT NULL,
|
|
31
|
+
version text NOT NULL DEFAULT '1.0.0',
|
|
32
|
+
status text NOT NULL DEFAULT 'active',
|
|
33
|
+
definition jsonb NOT NULL,
|
|
34
|
+
schema_hash text NOT NULL,
|
|
35
|
+
handler_path text NOT NULL,
|
|
36
|
+
schema_name text,
|
|
37
|
+
start_block bigint NOT NULL DEFAULT 0,
|
|
38
|
+
last_processed_block bigint NOT NULL DEFAULT 0,
|
|
39
|
+
reindex_from_block bigint,
|
|
40
|
+
reindex_to_block bigint,
|
|
41
|
+
last_error text,
|
|
42
|
+
last_error_at timestamptz,
|
|
43
|
+
total_processed bigint NOT NULL DEFAULT 0,
|
|
44
|
+
total_errors bigint NOT NULL DEFAULT 0,
|
|
45
|
+
account_id text NOT NULL,
|
|
46
|
+
handler_code text,
|
|
47
|
+
source_code text,
|
|
48
|
+
project_id uuid REFERENCES projects(id) ON DELETE SET NULL,
|
|
49
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
50
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
51
|
+
)
|
|
52
|
+
`.execute(db);
|
|
53
|
+
|
|
54
|
+
await sql`CREATE INDEX subgraphs_name_idx ON subgraphs (name)`.execute(db);
|
|
55
|
+
await sql`CREATE INDEX subgraphs_status_idx ON subgraphs (status)`.execute(
|
|
56
|
+
db,
|
|
57
|
+
);
|
|
58
|
+
await sql`CREATE UNIQUE INDEX subgraphs_name_account_id_unique ON subgraphs (name, account_id)`.execute(
|
|
59
|
+
db,
|
|
60
|
+
);
|
|
61
|
+
await sql`CREATE INDEX subgraphs_account_id_idx ON subgraphs (account_id)`.execute(
|
|
62
|
+
db,
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
await sql`
|
|
66
|
+
CREATE OR REPLACE FUNCTION notify_subgraph_changes() RETURNS trigger AS $$
|
|
67
|
+
BEGIN
|
|
68
|
+
PERFORM pg_notify('subgraph_changes', json_build_object(
|
|
69
|
+
'operation', TG_OP,
|
|
70
|
+
'name', COALESCE(NEW.name, OLD.name)
|
|
71
|
+
)::text);
|
|
72
|
+
RETURN COALESCE(NEW, OLD);
|
|
73
|
+
END;
|
|
74
|
+
$$ LANGUAGE plpgsql
|
|
75
|
+
`.execute(db);
|
|
76
|
+
|
|
77
|
+
await sql`DROP TRIGGER IF EXISTS subgraphs_notify_trigger ON subgraphs`.execute(
|
|
78
|
+
db,
|
|
79
|
+
);
|
|
80
|
+
await sql`
|
|
81
|
+
CREATE TRIGGER subgraphs_notify_trigger
|
|
82
|
+
AFTER INSERT OR UPDATE OR DELETE ON subgraphs
|
|
83
|
+
FOR EACH ROW EXECUTE FUNCTION notify_subgraph_changes()
|
|
84
|
+
`.execute(db);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (!(await tableExists(db, "subgraph_operations"))) {
|
|
88
|
+
await sql`
|
|
89
|
+
CREATE TABLE subgraph_operations (
|
|
90
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
91
|
+
subgraph_id uuid NOT NULL REFERENCES subgraphs(id) ON DELETE CASCADE,
|
|
92
|
+
subgraph_name text NOT NULL,
|
|
93
|
+
account_id text,
|
|
94
|
+
kind text NOT NULL CHECK (kind IN ('reindex', 'backfill')),
|
|
95
|
+
status text NOT NULL DEFAULT 'queued' CHECK (status IN ('queued', 'running', 'completed', 'failed', 'cancelled')),
|
|
96
|
+
from_block bigint,
|
|
97
|
+
to_block bigint,
|
|
98
|
+
cancel_requested boolean NOT NULL DEFAULT false,
|
|
99
|
+
locked_by text,
|
|
100
|
+
locked_until timestamptz,
|
|
101
|
+
started_at timestamptz,
|
|
102
|
+
finished_at timestamptz,
|
|
103
|
+
processed_blocks bigint,
|
|
104
|
+
error text,
|
|
105
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
106
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
107
|
+
)
|
|
108
|
+
`.execute(db);
|
|
109
|
+
|
|
110
|
+
await sql`
|
|
111
|
+
CREATE UNIQUE INDEX subgraph_operations_active_unique
|
|
112
|
+
ON subgraph_operations (subgraph_id)
|
|
113
|
+
WHERE status IN ('queued', 'running')
|
|
114
|
+
`.execute(db);
|
|
115
|
+
|
|
116
|
+
await sql`
|
|
117
|
+
CREATE INDEX subgraph_operations_claim_idx
|
|
118
|
+
ON subgraph_operations (created_at)
|
|
119
|
+
WHERE status = 'queued'
|
|
120
|
+
`.execute(db);
|
|
121
|
+
|
|
122
|
+
await sql`
|
|
123
|
+
CREATE INDEX subgraph_operations_stale_running_idx
|
|
124
|
+
ON subgraph_operations (locked_until)
|
|
125
|
+
WHERE status = 'running'
|
|
126
|
+
`.execute(db);
|
|
127
|
+
|
|
128
|
+
await sql`
|
|
129
|
+
CREATE OR REPLACE FUNCTION notify_subgraph_operation_new()
|
|
130
|
+
RETURNS trigger AS $$
|
|
131
|
+
BEGIN
|
|
132
|
+
PERFORM pg_notify('subgraph_operations:new', NEW.id::text);
|
|
133
|
+
RETURN NEW;
|
|
134
|
+
END;
|
|
135
|
+
$$ LANGUAGE plpgsql
|
|
136
|
+
`.execute(db);
|
|
137
|
+
|
|
138
|
+
await sql`DROP TRIGGER IF EXISTS subgraph_operations_insert_notify ON subgraph_operations`.execute(
|
|
139
|
+
db,
|
|
140
|
+
);
|
|
141
|
+
await sql`
|
|
142
|
+
CREATE TRIGGER subgraph_operations_insert_notify
|
|
143
|
+
AFTER INSERT ON subgraph_operations
|
|
144
|
+
FOR EACH ROW
|
|
145
|
+
WHEN (NEW.status = 'queued')
|
|
146
|
+
EXECUTE FUNCTION notify_subgraph_operation_new()
|
|
147
|
+
`.execute(db);
|
|
148
|
+
|
|
149
|
+
await sql`DROP TRIGGER IF EXISTS subgraph_operations_cancel_notify ON subgraph_operations`.execute(
|
|
150
|
+
db,
|
|
151
|
+
);
|
|
152
|
+
await sql`
|
|
153
|
+
CREATE TRIGGER subgraph_operations_cancel_notify
|
|
154
|
+
AFTER UPDATE OF cancel_requested ON subgraph_operations
|
|
155
|
+
FOR EACH ROW
|
|
156
|
+
WHEN (NEW.cancel_requested = true AND OLD.cancel_requested IS DISTINCT FROM NEW.cancel_requested)
|
|
157
|
+
EXECUTE FUNCTION notify_subgraph_operation_new()
|
|
158
|
+
`.execute(db);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export async function down(_db: Kysely<unknown>): Promise<void> {
|
|
163
|
+
// No-op. Rolling back would drop tables that existed pre-migration on the
|
|
164
|
+
// dedicated-tenant + OSS code paths and risk data loss on platform once the
|
|
165
|
+
// processor starts writing. If a true rollback is needed, do it manually.
|
|
166
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type Kysely, sql } from "kysely";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Mark the `tenants` table deprecated. The 2026-05-14 shared-rip pivot
|
|
5
|
+
* collapsed the dedicated per-tenant model — no live writers remain. Rows
|
|
6
|
+
* are preserved here for post-pivot reconciliation. A follow-up migration
|
|
7
|
+
* will `DROP TABLE` after a 2-cycle observation window when we're sure no
|
|
8
|
+
* Stripe-dormant reader references `tenants.plan`.
|
|
9
|
+
*/
|
|
10
|
+
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
11
|
+
await sql`
|
|
12
|
+
COMMENT ON TABLE tenants IS
|
|
13
|
+
'DEPRECATED 2026-05-16: post shared-rip, no live writers. Drop after observation window.'
|
|
14
|
+
`.execute(db);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export async function down(_db: Kysely<unknown>): Promise<void> {
|
|
18
|
+
// No-op — restoring the comment to nothing on rollback is not useful.
|
|
19
|
+
}
|