@secondlayer/shared 2.1.0 → 3.0.0-beta.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.
- package/README.md +2 -2
- package/dist/src/crypto/secrets.js +47 -3
- package/dist/src/crypto/secrets.js.map +5 -4
- package/dist/src/db/index.d.ts +112 -137
- package/dist/src/db/index.js.map +2 -2
- package/dist/src/db/jsonb.d.ts +5 -1
- package/dist/src/db/jsonb.js.map +2 -2
- package/dist/src/db/queries/account-spend-caps.d.ts +444 -0
- package/dist/src/db/queries/account-spend-caps.js +60 -0
- package/dist/src/db/queries/account-spend-caps.js.map +10 -0
- package/dist/src/db/queries/account-usage.d.ts +468 -0
- package/dist/src/db/queries/account-usage.js +222 -0
- package/dist/src/db/queries/account-usage.js.map +11 -0
- package/dist/src/db/queries/accounts.d.ts +100 -109
- package/dist/src/db/queries/accounts.js +15 -1
- package/dist/src/db/queries/accounts.js.map +3 -3
- package/dist/src/db/queries/integrity.d.ts +85 -107
- package/dist/src/db/queries/projects.d.ts +87 -109
- package/dist/src/db/queries/provisioning-audit.d.ts +85 -107
- package/dist/src/db/queries/subgraph-gaps.d.ts +85 -107
- package/dist/src/db/queries/subgraphs.d.ts +86 -109
- package/dist/src/db/queries/subgraphs.js +2 -3
- package/dist/src/db/queries/subgraphs.js.map +4 -4
- package/dist/src/db/queries/{workflows.d.ts → tenant-compute-addons.d.ts} +108 -142
- package/dist/src/db/queries/tenant-compute-addons.js +47 -0
- package/dist/src/db/queries/tenant-compute-addons.js.map +10 -0
- package/dist/src/db/queries/tenants.d.ts +98 -110
- package/dist/src/db/queries/tenants.js +55 -8
- package/dist/src/db/queries/tenants.js.map +6 -5
- package/dist/src/db/queries/usage.d.ts +86 -132
- package/dist/src/db/queries/usage.js +5 -64
- package/dist/src/db/queries/usage.js.map +4 -5
- package/dist/src/db/schema.d.ts +107 -136
- package/dist/src/errors.d.ts +8 -7
- package/dist/src/errors.js +11 -12
- package/dist/src/errors.js.map +3 -3
- package/dist/src/index.d.ts +119 -143
- package/dist/src/index.js +11 -12
- package/dist/src/index.js.map +4 -4
- package/dist/src/node/local-client.d.ts +85 -107
- package/dist/src/pricing.d.ts +20 -1
- package/dist/src/pricing.js +58 -1
- package/dist/src/pricing.js.map +3 -3
- package/migrations/0045_drop_marketplace_columns.ts +47 -0
- package/migrations/0046_tenant_activity_signal.ts +47 -0
- package/migrations/0047_usage_daily_tenant_id.ts +73 -0
- package/migrations/0048_tenant_compute_addons.ts +49 -0
- package/migrations/0049_accounts_stripe_customer_id.ts +30 -0
- package/migrations/0050_account_spend_caps.ts +45 -0
- package/migrations/0051_workflow_ai_usage_daily.ts +40 -0
- package/migrations/0052_sentries.ts +61 -0
- package/migrations/0053_workflow_runtime.ts +88 -0
- package/migrations/0054_accounts_plan_hobby.ts +32 -0
- package/migrations/0055_ai_usage_account_scope.ts +108 -0
- package/migrations/0056_drop_workflow_sentry_residuals.ts +23 -0
- package/migrations/0057_subscriptions.ts +137 -0
- package/package.json +26 -14
- package/dist/src/db/queries/workflows.js +0 -260
- package/dist/src/db/queries/workflows.js.map +0 -12
- package/dist/src/lib/plans.d.ts +0 -9
- package/dist/src/lib/plans.js +0 -37
- package/dist/src/lib/plans.js.map +0 -10
- package/dist/src/schemas/workflows.d.ts +0 -70
- package/dist/src/schemas/workflows.js +0 -43
- package/dist/src/schemas/workflows.js.map +0 -10
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
import { Kysely } from "kysely";
|
|
2
|
+
import { ColumnType, Generated } from "kysely";
|
|
3
|
+
interface BlocksTable {
|
|
4
|
+
height: number;
|
|
5
|
+
hash: string;
|
|
6
|
+
parent_hash: string;
|
|
7
|
+
burn_block_height: number;
|
|
8
|
+
timestamp: number;
|
|
9
|
+
canonical: Generated<boolean>;
|
|
10
|
+
created_at: Generated<Date>;
|
|
11
|
+
}
|
|
12
|
+
interface TransactionsTable {
|
|
13
|
+
tx_id: string;
|
|
14
|
+
block_height: number;
|
|
15
|
+
tx_index: Generated<number>;
|
|
16
|
+
type: string;
|
|
17
|
+
sender: string;
|
|
18
|
+
status: string;
|
|
19
|
+
contract_id: string | null;
|
|
20
|
+
function_name: string | null;
|
|
21
|
+
function_args: Generated<unknown | null>;
|
|
22
|
+
raw_result: Generated<string | null>;
|
|
23
|
+
raw_tx: string;
|
|
24
|
+
created_at: Generated<Date>;
|
|
25
|
+
}
|
|
26
|
+
interface EventsTable {
|
|
27
|
+
id: Generated<string>;
|
|
28
|
+
tx_id: string;
|
|
29
|
+
block_height: number;
|
|
30
|
+
event_index: number;
|
|
31
|
+
type: string;
|
|
32
|
+
data: unknown;
|
|
33
|
+
created_at: Generated<Date>;
|
|
34
|
+
}
|
|
35
|
+
interface IndexProgressTable {
|
|
36
|
+
network: string;
|
|
37
|
+
last_indexed_block: Generated<number>;
|
|
38
|
+
last_contiguous_block: Generated<number>;
|
|
39
|
+
highest_seen_block: Generated<number>;
|
|
40
|
+
updated_at: Generated<Date>;
|
|
41
|
+
}
|
|
42
|
+
interface SubgraphsTable {
|
|
43
|
+
id: Generated<string>;
|
|
44
|
+
name: string;
|
|
45
|
+
version: Generated<string>;
|
|
46
|
+
status: Generated<string>;
|
|
47
|
+
definition: Record<string, unknown>;
|
|
48
|
+
schema_hash: string;
|
|
49
|
+
handler_path: string;
|
|
50
|
+
schema_name: string | null;
|
|
51
|
+
start_block: Generated<number>;
|
|
52
|
+
last_processed_block: Generated<number>;
|
|
53
|
+
reindex_from_block: number | null;
|
|
54
|
+
reindex_to_block: number | null;
|
|
55
|
+
last_error: string | null;
|
|
56
|
+
last_error_at: Date | null;
|
|
57
|
+
total_processed: Generated<number>;
|
|
58
|
+
total_errors: Generated<number>;
|
|
59
|
+
account_id: string;
|
|
60
|
+
handler_code: string | null;
|
|
61
|
+
source_code: string | null;
|
|
62
|
+
project_id: string | null;
|
|
63
|
+
created_at: Generated<Date>;
|
|
64
|
+
updated_at: Generated<Date>;
|
|
65
|
+
}
|
|
66
|
+
interface SubgraphGapsTable {
|
|
67
|
+
id: Generated<string>;
|
|
68
|
+
subgraph_id: string;
|
|
69
|
+
subgraph_name: string;
|
|
70
|
+
gap_start: number;
|
|
71
|
+
gap_end: number;
|
|
72
|
+
reason: string;
|
|
73
|
+
detected_at: Generated<Date>;
|
|
74
|
+
resolved_at: Date | null;
|
|
75
|
+
}
|
|
76
|
+
interface ApiKeysTable {
|
|
77
|
+
id: Generated<string>;
|
|
78
|
+
key_hash: string;
|
|
79
|
+
key_prefix: string;
|
|
80
|
+
name: string | null;
|
|
81
|
+
status: Generated<string>;
|
|
82
|
+
rate_limit: Generated<number>;
|
|
83
|
+
ip_address: string;
|
|
84
|
+
account_id: string;
|
|
85
|
+
last_used_at: Date | null;
|
|
86
|
+
revoked_at: Date | null;
|
|
87
|
+
created_at: Generated<Date>;
|
|
88
|
+
}
|
|
89
|
+
interface AccountsTable {
|
|
90
|
+
id: Generated<string>;
|
|
91
|
+
email: string;
|
|
92
|
+
plan: Generated<string>;
|
|
93
|
+
display_name: string | null;
|
|
94
|
+
bio: string | null;
|
|
95
|
+
avatar_url: string | null;
|
|
96
|
+
slug: string | null;
|
|
97
|
+
stripe_customer_id: string | null;
|
|
98
|
+
created_at: Generated<Date>;
|
|
99
|
+
}
|
|
100
|
+
interface SessionsTable {
|
|
101
|
+
id: Generated<string>;
|
|
102
|
+
token_hash: string;
|
|
103
|
+
token_prefix: string;
|
|
104
|
+
account_id: string;
|
|
105
|
+
ip_address: string;
|
|
106
|
+
expires_at: Generated<Date>;
|
|
107
|
+
revoked_at: Date | null;
|
|
108
|
+
last_used_at: Date | null;
|
|
109
|
+
created_at: Generated<Date>;
|
|
110
|
+
}
|
|
111
|
+
interface MagicLinksTable {
|
|
112
|
+
id: Generated<string>;
|
|
113
|
+
email: string;
|
|
114
|
+
token: string;
|
|
115
|
+
code: string | null;
|
|
116
|
+
expires_at: Date;
|
|
117
|
+
used_at: Date | null;
|
|
118
|
+
failed_attempts: Generated<number>;
|
|
119
|
+
created_at: Generated<Date>;
|
|
120
|
+
}
|
|
121
|
+
interface UsageDailyTable {
|
|
122
|
+
account_id: string;
|
|
123
|
+
tenant_id: string | null;
|
|
124
|
+
date: string;
|
|
125
|
+
api_requests: Generated<number>;
|
|
126
|
+
deliveries: Generated<number>;
|
|
127
|
+
}
|
|
128
|
+
interface UsageSnapshotsTable {
|
|
129
|
+
id: Generated<string>;
|
|
130
|
+
account_id: string;
|
|
131
|
+
measured_at: Generated<Date>;
|
|
132
|
+
storage_bytes: Generated<number>;
|
|
133
|
+
}
|
|
134
|
+
interface WaitlistTable {
|
|
135
|
+
id: Generated<string>;
|
|
136
|
+
email: string;
|
|
137
|
+
source: Generated<string>;
|
|
138
|
+
status: Generated<string>;
|
|
139
|
+
created_at: Generated<Date>;
|
|
140
|
+
}
|
|
141
|
+
interface AccountInsightsTable {
|
|
142
|
+
id: Generated<string>;
|
|
143
|
+
account_id: string;
|
|
144
|
+
category: string;
|
|
145
|
+
insight_type: string;
|
|
146
|
+
resource_id: string | null;
|
|
147
|
+
severity: string;
|
|
148
|
+
title: string;
|
|
149
|
+
body: string;
|
|
150
|
+
data: unknown;
|
|
151
|
+
dismissed_at: Date | null;
|
|
152
|
+
expires_at: Date | null;
|
|
153
|
+
created_at: Generated<Date>;
|
|
154
|
+
}
|
|
155
|
+
interface AccountAgentRunsTable {
|
|
156
|
+
id: Generated<string>;
|
|
157
|
+
account_id: string;
|
|
158
|
+
started_at: Generated<Date>;
|
|
159
|
+
completed_at: Date | null;
|
|
160
|
+
status: Generated<string>;
|
|
161
|
+
input_tokens: Generated<number>;
|
|
162
|
+
output_tokens: Generated<number>;
|
|
163
|
+
cost_usd: Generated<number>;
|
|
164
|
+
insights_created: Generated<number>;
|
|
165
|
+
error: string | null;
|
|
166
|
+
}
|
|
167
|
+
interface SubgraphProcessingStatsTable {
|
|
168
|
+
id: Generated<string>;
|
|
169
|
+
subgraph_name: string;
|
|
170
|
+
api_key_id: string | null;
|
|
171
|
+
bucket_start: Date | null;
|
|
172
|
+
bucket_end: Date | null;
|
|
173
|
+
blocks_processed: number | null;
|
|
174
|
+
total_time_ms: number | null;
|
|
175
|
+
handler_time_ms: number | null;
|
|
176
|
+
flush_time_ms: number | null;
|
|
177
|
+
max_block_time_ms: number | null;
|
|
178
|
+
max_handler_time_ms: number | null;
|
|
179
|
+
avg_ops_per_block: number | null;
|
|
180
|
+
is_catchup: Generated<boolean>;
|
|
181
|
+
created_at: Generated<Date>;
|
|
182
|
+
}
|
|
183
|
+
interface SubgraphTableSnapshotsTable {
|
|
184
|
+
id: Generated<string>;
|
|
185
|
+
subgraph_name: string;
|
|
186
|
+
api_key_id: string | null;
|
|
187
|
+
table_name: string;
|
|
188
|
+
row_count: number | null;
|
|
189
|
+
created_at: Generated<Date>;
|
|
190
|
+
}
|
|
191
|
+
interface SubgraphHealthSnapshotsTable {
|
|
192
|
+
id: Generated<string>;
|
|
193
|
+
subgraph_id: string;
|
|
194
|
+
total_processed: number;
|
|
195
|
+
total_errors: number;
|
|
196
|
+
last_processed_block: number | null;
|
|
197
|
+
captured_at: Generated<Date>;
|
|
198
|
+
}
|
|
199
|
+
interface SubgraphUsageDailyTable {
|
|
200
|
+
subgraph_id: string;
|
|
201
|
+
date: string;
|
|
202
|
+
query_count: Generated<number>;
|
|
203
|
+
}
|
|
204
|
+
interface ProjectsTable {
|
|
205
|
+
id: Generated<string>;
|
|
206
|
+
name: string;
|
|
207
|
+
slug: string;
|
|
208
|
+
account_id: string;
|
|
209
|
+
settings: Generated<Record<string, unknown>>;
|
|
210
|
+
network: Generated<string>;
|
|
211
|
+
node_rpc: string | null;
|
|
212
|
+
created_at: Generated<Date>;
|
|
213
|
+
updated_at: Generated<Date>;
|
|
214
|
+
}
|
|
215
|
+
interface TeamMembersTable {
|
|
216
|
+
id: Generated<string>;
|
|
217
|
+
project_id: string;
|
|
218
|
+
account_id: string;
|
|
219
|
+
role: Generated<string>;
|
|
220
|
+
invited_by: string | null;
|
|
221
|
+
created_at: Generated<Date>;
|
|
222
|
+
}
|
|
223
|
+
interface TeamInvitationsTable {
|
|
224
|
+
id: Generated<string>;
|
|
225
|
+
project_id: string;
|
|
226
|
+
email: string;
|
|
227
|
+
role: Generated<string>;
|
|
228
|
+
token: string;
|
|
229
|
+
invited_by: string | null;
|
|
230
|
+
expires_at: Date;
|
|
231
|
+
accepted_at: Date | null;
|
|
232
|
+
created_at: Generated<Date>;
|
|
233
|
+
}
|
|
234
|
+
interface ChatSessionsTable {
|
|
235
|
+
id: Generated<string>;
|
|
236
|
+
account_id: string;
|
|
237
|
+
title: string | null;
|
|
238
|
+
summary: unknown | null;
|
|
239
|
+
created_at: Generated<Date>;
|
|
240
|
+
updated_at: Generated<Date>;
|
|
241
|
+
}
|
|
242
|
+
interface ChatMessagesTable {
|
|
243
|
+
id: Generated<string>;
|
|
244
|
+
chat_session_id: string;
|
|
245
|
+
role: string;
|
|
246
|
+
parts: unknown;
|
|
247
|
+
metadata: unknown | null;
|
|
248
|
+
created_at: Generated<Date>;
|
|
249
|
+
}
|
|
250
|
+
interface Database {
|
|
251
|
+
blocks: BlocksTable;
|
|
252
|
+
transactions: TransactionsTable;
|
|
253
|
+
events: EventsTable;
|
|
254
|
+
index_progress: IndexProgressTable;
|
|
255
|
+
subgraphs: SubgraphsTable;
|
|
256
|
+
api_keys: ApiKeysTable;
|
|
257
|
+
accounts: AccountsTable;
|
|
258
|
+
sessions: SessionsTable;
|
|
259
|
+
magic_links: MagicLinksTable;
|
|
260
|
+
usage_daily: UsageDailyTable;
|
|
261
|
+
usage_snapshots: UsageSnapshotsTable;
|
|
262
|
+
waitlist: WaitlistTable;
|
|
263
|
+
account_insights: AccountInsightsTable;
|
|
264
|
+
account_agent_runs: AccountAgentRunsTable;
|
|
265
|
+
subgraph_health_snapshots: SubgraphHealthSnapshotsTable;
|
|
266
|
+
subgraph_processing_stats: SubgraphProcessingStatsTable;
|
|
267
|
+
subgraph_table_snapshots: SubgraphTableSnapshotsTable;
|
|
268
|
+
subgraph_gaps: SubgraphGapsTable;
|
|
269
|
+
subgraph_usage_daily: SubgraphUsageDailyTable;
|
|
270
|
+
projects: ProjectsTable;
|
|
271
|
+
team_members: TeamMembersTable;
|
|
272
|
+
team_invitations: TeamInvitationsTable;
|
|
273
|
+
chat_sessions: ChatSessionsTable;
|
|
274
|
+
chat_messages: ChatMessagesTable;
|
|
275
|
+
tenants: TenantsTable;
|
|
276
|
+
tenant_usage_monthly: TenantUsageMonthlyTable;
|
|
277
|
+
tenant_compute_addons: TenantComputeAddonsTable;
|
|
278
|
+
account_spend_caps: AccountSpendCapsTable;
|
|
279
|
+
provisioning_audit_log: ProvisioningAuditLogTable;
|
|
280
|
+
subscriptions: SubscriptionsTable;
|
|
281
|
+
subscription_outbox: SubscriptionOutboxTable;
|
|
282
|
+
subscription_deliveries: SubscriptionDeliveriesTable;
|
|
283
|
+
}
|
|
284
|
+
type TenantStatus = "provisioning" | "active" | "suspended" | "error" | "deleted";
|
|
285
|
+
interface TenantsTable {
|
|
286
|
+
id: Generated<string>;
|
|
287
|
+
account_id: string;
|
|
288
|
+
slug: string;
|
|
289
|
+
status: ColumnType<TenantStatus, TenantStatus | undefined, TenantStatus>;
|
|
290
|
+
plan: string;
|
|
291
|
+
cpus: ColumnType<number, number | string, number | string>;
|
|
292
|
+
memory_mb: number;
|
|
293
|
+
storage_limit_mb: number;
|
|
294
|
+
storage_used_mb: number | null;
|
|
295
|
+
pg_container_id: string | null;
|
|
296
|
+
api_container_id: string | null;
|
|
297
|
+
processor_container_id: string | null;
|
|
298
|
+
target_database_url_enc: Buffer;
|
|
299
|
+
tenant_jwt_secret_enc: Buffer;
|
|
300
|
+
anon_key_enc: Buffer;
|
|
301
|
+
service_key_enc: Buffer;
|
|
302
|
+
api_url_internal: string;
|
|
303
|
+
api_url_public: string;
|
|
304
|
+
suspended_at: Date | null;
|
|
305
|
+
last_health_check_at: Date | null;
|
|
306
|
+
last_active_at: Generated<Date>;
|
|
307
|
+
service_gen: Generated<number>;
|
|
308
|
+
anon_gen: Generated<number>;
|
|
309
|
+
project_id: string | null;
|
|
310
|
+
created_at: Generated<Date>;
|
|
311
|
+
updated_at: Generated<Date>;
|
|
312
|
+
}
|
|
313
|
+
interface TenantUsageMonthlyTable {
|
|
314
|
+
id: Generated<string>;
|
|
315
|
+
tenant_id: string;
|
|
316
|
+
period_month: Date;
|
|
317
|
+
storage_peak_mb: Generated<number>;
|
|
318
|
+
storage_avg_mb: Generated<number>;
|
|
319
|
+
storage_last_mb: Generated<number>;
|
|
320
|
+
measurements: Generated<number>;
|
|
321
|
+
first_at: Generated<Date>;
|
|
322
|
+
last_at: Generated<Date>;
|
|
323
|
+
}
|
|
324
|
+
interface TenantComputeAddonsTable {
|
|
325
|
+
id: Generated<string>;
|
|
326
|
+
tenant_id: string;
|
|
327
|
+
memory_mb_delta: Generated<number>;
|
|
328
|
+
cpu_delta: Generated<number | string>;
|
|
329
|
+
storage_mb_delta: Generated<number>;
|
|
330
|
+
effective_from: Generated<Date>;
|
|
331
|
+
effective_until: Date | null;
|
|
332
|
+
stripe_subscription_item_id: string | null;
|
|
333
|
+
created_at: Generated<Date>;
|
|
334
|
+
}
|
|
335
|
+
interface AccountSpendCapsTable {
|
|
336
|
+
account_id: string;
|
|
337
|
+
monthly_cap_cents: number | null;
|
|
338
|
+
compute_cap_cents: number | null;
|
|
339
|
+
storage_cap_cents: number | null;
|
|
340
|
+
ai_cap_cents: number | null;
|
|
341
|
+
alert_threshold_pct: Generated<number>;
|
|
342
|
+
alert_sent_at: Date | null;
|
|
343
|
+
frozen_at: Date | null;
|
|
344
|
+
updated_at: Generated<Date>;
|
|
345
|
+
}
|
|
346
|
+
type ProvisioningAuditEvent = "provision.start" | "provision.success" | "provision.failure" | "suspend" | "resume" | "resize" | "keys.rotate" | "bastion.key.upload" | "bastion.key.revoke" | "teardown";
|
|
347
|
+
type ProvisioningAuditStatus = "ok" | "error";
|
|
348
|
+
interface ProvisioningAuditLogTable {
|
|
349
|
+
id: Generated<string>;
|
|
350
|
+
tenant_id: string | null;
|
|
351
|
+
tenant_slug: string | null;
|
|
352
|
+
account_id: string | null;
|
|
353
|
+
actor: string;
|
|
354
|
+
event: ProvisioningAuditEvent;
|
|
355
|
+
status: ProvisioningAuditStatus;
|
|
356
|
+
detail: unknown | null;
|
|
357
|
+
error: string | null;
|
|
358
|
+
created_at: Generated<Date>;
|
|
359
|
+
}
|
|
360
|
+
type SubscriptionStatus = "active" | "paused" | "error";
|
|
361
|
+
type SubscriptionFormat = "standard-webhooks" | "inngest" | "trigger" | "cloudflare" | "cloudevents" | "raw";
|
|
362
|
+
type SubscriptionRuntime = "inngest" | "trigger" | "cloudflare" | "node";
|
|
363
|
+
interface SubscriptionsTable {
|
|
364
|
+
id: Generated<string>;
|
|
365
|
+
account_id: string;
|
|
366
|
+
project_id: string | null;
|
|
367
|
+
name: string;
|
|
368
|
+
status: ColumnType<SubscriptionStatus, SubscriptionStatus | undefined, SubscriptionStatus>;
|
|
369
|
+
subgraph_name: string;
|
|
370
|
+
table_name: string;
|
|
371
|
+
filter: Generated<unknown>;
|
|
372
|
+
format: ColumnType<SubscriptionFormat, SubscriptionFormat | undefined, SubscriptionFormat>;
|
|
373
|
+
runtime: SubscriptionRuntime | null;
|
|
374
|
+
url: string;
|
|
375
|
+
signing_secret_enc: Buffer;
|
|
376
|
+
auth_config: Generated<unknown>;
|
|
377
|
+
max_retries: Generated<number>;
|
|
378
|
+
timeout_ms: Generated<number>;
|
|
379
|
+
concurrency: Generated<number>;
|
|
380
|
+
circuit_failures: Generated<number>;
|
|
381
|
+
circuit_opened_at: Date | null;
|
|
382
|
+
last_delivery_at: Date | null;
|
|
383
|
+
last_success_at: Date | null;
|
|
384
|
+
last_error: string | null;
|
|
385
|
+
created_at: Generated<Date>;
|
|
386
|
+
updated_at: Generated<Date>;
|
|
387
|
+
}
|
|
388
|
+
type OutboxStatus = "pending" | "delivered" | "dead";
|
|
389
|
+
interface SubscriptionOutboxTable {
|
|
390
|
+
id: Generated<string>;
|
|
391
|
+
subscription_id: string;
|
|
392
|
+
subgraph_name: string;
|
|
393
|
+
table_name: string;
|
|
394
|
+
block_height: number | bigint;
|
|
395
|
+
tx_id: string | null;
|
|
396
|
+
row_pk: unknown;
|
|
397
|
+
event_type: string;
|
|
398
|
+
payload: unknown;
|
|
399
|
+
dedup_key: string;
|
|
400
|
+
attempt: Generated<number>;
|
|
401
|
+
next_attempt_at: Generated<Date>;
|
|
402
|
+
status: ColumnType<OutboxStatus, OutboxStatus | undefined, OutboxStatus>;
|
|
403
|
+
is_replay: Generated<boolean>;
|
|
404
|
+
delivered_at: Date | null;
|
|
405
|
+
failed_at: Date | null;
|
|
406
|
+
locked_by: string | null;
|
|
407
|
+
locked_until: Date | null;
|
|
408
|
+
created_at: Generated<Date>;
|
|
409
|
+
}
|
|
410
|
+
interface SubscriptionDeliveriesTable {
|
|
411
|
+
id: Generated<string>;
|
|
412
|
+
outbox_id: string;
|
|
413
|
+
subscription_id: string;
|
|
414
|
+
attempt: number;
|
|
415
|
+
status_code: number | null;
|
|
416
|
+
response_headers: unknown | null;
|
|
417
|
+
response_body: string | null;
|
|
418
|
+
error_message: string | null;
|
|
419
|
+
duration_ms: number | null;
|
|
420
|
+
dispatched_at: Generated<Date>;
|
|
421
|
+
}
|
|
422
|
+
interface SparklinePoint {
|
|
423
|
+
day: string;
|
|
424
|
+
value: number;
|
|
425
|
+
}
|
|
426
|
+
interface ComputeUsage {
|
|
427
|
+
usedHours: number;
|
|
428
|
+
allowanceHours: number;
|
|
429
|
+
pct: number;
|
|
430
|
+
sparkline: SparklinePoint[];
|
|
431
|
+
}
|
|
432
|
+
interface StorageUsage {
|
|
433
|
+
usedBytes: number;
|
|
434
|
+
allowanceBytes: number;
|
|
435
|
+
pct: number;
|
|
436
|
+
sparkline: SparklinePoint[];
|
|
437
|
+
}
|
|
438
|
+
interface AiUsage {
|
|
439
|
+
todayCount: number;
|
|
440
|
+
periodCount: number;
|
|
441
|
+
dailyCap: number;
|
|
442
|
+
pct: number;
|
|
443
|
+
sparkline: SparklinePoint[];
|
|
444
|
+
}
|
|
445
|
+
interface ProjectRow {
|
|
446
|
+
id: string;
|
|
447
|
+
slug: string;
|
|
448
|
+
name: string;
|
|
449
|
+
status: string;
|
|
450
|
+
subgraphCount: number;
|
|
451
|
+
compute: {
|
|
452
|
+
hours: number
|
|
453
|
+
pct: number
|
|
454
|
+
};
|
|
455
|
+
storage: {
|
|
456
|
+
bytes: number
|
|
457
|
+
pct: number
|
|
458
|
+
};
|
|
459
|
+
aiEvals: {
|
|
460
|
+
todayCount: number
|
|
461
|
+
pct: number
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
declare function getComputeUsage(db: Kysely<Database>, accountId: string, plan: string, periodStart: Date, now?: Date): Promise<ComputeUsage>;
|
|
465
|
+
declare function getStorageUsage(db: Kysely<Database>, accountId: string, plan: string, now?: Date): Promise<StorageUsage>;
|
|
466
|
+
declare function getAiUsage(_db: Kysely<Database>, _accountId: string, plan: string, _periodStart: Date, now?: Date): Promise<AiUsage>;
|
|
467
|
+
declare function getProjectBreakdown(db: Kysely<Database>, accountId: string, plan: string, periodStart: Date, now?: Date): Promise<ProjectRow[]>;
|
|
468
|
+
export { getStorageUsage, getProjectBreakdown, getComputeUsage, getAiUsage, StorageUsage, SparklinePoint, ProjectRow, ComputeUsage, AiUsage };
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __returnValue = (v) => v;
|
|
4
|
+
function __exportSetter(name, newValue) {
|
|
5
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
6
|
+
}
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, {
|
|
10
|
+
get: all[name],
|
|
11
|
+
enumerable: true,
|
|
12
|
+
configurable: true,
|
|
13
|
+
set: __exportSetter.bind(all, name)
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// src/pricing.ts
|
|
18
|
+
var MODEL_PRICING = {
|
|
19
|
+
anthropic: {
|
|
20
|
+
"claude-haiku-4-5": { inputPerMTokens: 1, outputPerMTokens: 5 },
|
|
21
|
+
"claude-haiku-4-5-20251001": { inputPerMTokens: 1, outputPerMTokens: 5 },
|
|
22
|
+
"claude-sonnet-4-6": { inputPerMTokens: 3, outputPerMTokens: 15 },
|
|
23
|
+
"claude-opus-4-7": { inputPerMTokens: 15, outputPerMTokens: 75 }
|
|
24
|
+
},
|
|
25
|
+
openai: {
|
|
26
|
+
"gpt-4.1": { inputPerMTokens: 2.5, outputPerMTokens: 10 },
|
|
27
|
+
"gpt-4o": { inputPerMTokens: 2.5, outputPerMTokens: 10 },
|
|
28
|
+
"gpt-4o-mini": { inputPerMTokens: 0.15, outputPerMTokens: 0.6 }
|
|
29
|
+
},
|
|
30
|
+
google: {
|
|
31
|
+
"gemini-2.5-pro": { inputPerMTokens: 1.25, outputPerMTokens: 10 },
|
|
32
|
+
"gemini-2.5-flash": { inputPerMTokens: 0.3, outputPerMTokens: 2.5 }
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
function computeUsdCost(provider, modelId, usage) {
|
|
36
|
+
const p = MODEL_PRICING[provider]?.[modelId];
|
|
37
|
+
if (!p)
|
|
38
|
+
return null;
|
|
39
|
+
return usage.inputTokens * p.inputPerMTokens / 1e6 + usage.outputTokens * p.outputPerMTokens / 1e6;
|
|
40
|
+
}
|
|
41
|
+
var AI_CAP_UNLIMITED = {
|
|
42
|
+
evalsPerDay: Number.POSITIVE_INFINITY,
|
|
43
|
+
overageMeterEventName: "ai_evals"
|
|
44
|
+
};
|
|
45
|
+
var AI_CAPS_BY_PLAN = {
|
|
46
|
+
hobby: { evalsPerDay: 50, overageMeterEventName: "ai_evals" },
|
|
47
|
+
launch: { evalsPerDay: 500, overageMeterEventName: "ai_evals" },
|
|
48
|
+
grow: { evalsPerDay: 1000, overageMeterEventName: "ai_evals" },
|
|
49
|
+
scale: { evalsPerDay: 2500, overageMeterEventName: "ai_evals" },
|
|
50
|
+
enterprise: AI_CAP_UNLIMITED
|
|
51
|
+
};
|
|
52
|
+
function getAiCapForPlan(plan) {
|
|
53
|
+
return AI_CAPS_BY_PLAN[plan] ?? AI_CAPS_BY_PLAN.hobby;
|
|
54
|
+
}
|
|
55
|
+
var BYTES_PER_GB = 1024 ** 3;
|
|
56
|
+
var COMPUTE_ALLOWANCE_BY_PLAN = {
|
|
57
|
+
hobby: Number.POSITIVE_INFINITY,
|
|
58
|
+
launch: 500,
|
|
59
|
+
grow: 1000,
|
|
60
|
+
scale: 2500,
|
|
61
|
+
enterprise: Number.POSITIVE_INFINITY
|
|
62
|
+
};
|
|
63
|
+
var STORAGE_ALLOWANCE_BYTES_BY_PLAN = {
|
|
64
|
+
hobby: 5 * BYTES_PER_GB,
|
|
65
|
+
launch: 50 * BYTES_PER_GB,
|
|
66
|
+
grow: 200 * BYTES_PER_GB,
|
|
67
|
+
scale: 1000 * BYTES_PER_GB,
|
|
68
|
+
enterprise: Number.POSITIVE_INFINITY
|
|
69
|
+
};
|
|
70
|
+
function getComputeAllowanceHours(plan) {
|
|
71
|
+
return COMPUTE_ALLOWANCE_BY_PLAN[plan] ?? COMPUTE_ALLOWANCE_BY_PLAN.hobby;
|
|
72
|
+
}
|
|
73
|
+
function getStorageAllowanceBytes(plan) {
|
|
74
|
+
return STORAGE_ALLOWANCE_BYTES_BY_PLAN[plan] ?? STORAGE_ALLOWANCE_BYTES_BY_PLAN.hobby;
|
|
75
|
+
}
|
|
76
|
+
function hasStorageOverage(plan) {
|
|
77
|
+
return plan !== "hobby";
|
|
78
|
+
}
|
|
79
|
+
var BASE_PRICE_CENTS_BY_PLAN = {
|
|
80
|
+
hobby: 0,
|
|
81
|
+
launch: 14900,
|
|
82
|
+
grow: 34900,
|
|
83
|
+
scale: 79900,
|
|
84
|
+
enterprise: 0
|
|
85
|
+
};
|
|
86
|
+
function getBasePriceCents(plan) {
|
|
87
|
+
return BASE_PRICE_CENTS_BY_PLAN[plan] ?? 0;
|
|
88
|
+
}
|
|
89
|
+
function getPlanDisplayName(plan) {
|
|
90
|
+
return plan.charAt(0).toUpperCase() + plan.slice(1);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// src/db/queries/account-usage.ts
|
|
94
|
+
import { sql } from "kysely";
|
|
95
|
+
var IDLE_GRACE_MS = 2 * 60 * 60 * 1000;
|
|
96
|
+
var BYTES_PER_MB = 1024 * 1024;
|
|
97
|
+
function toDayKey(d) {
|
|
98
|
+
return d.toISOString().slice(0, 10);
|
|
99
|
+
}
|
|
100
|
+
function* lastNDays(n, endInclusive) {
|
|
101
|
+
const end = new Date(endInclusive);
|
|
102
|
+
for (let i = n - 1;i >= 0; i--) {
|
|
103
|
+
const d = new Date(end);
|
|
104
|
+
d.setUTCDate(d.getUTCDate() - i);
|
|
105
|
+
yield toDayKey(d);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function computeActiveHours(periodStart, now, tenant) {
|
|
109
|
+
if (tenant.status !== "active")
|
|
110
|
+
return 0;
|
|
111
|
+
const rangeStart = Math.max(periodStart.getTime(), tenant.created_at.getTime());
|
|
112
|
+
const rangeEnd = Math.min(now.getTime(), tenant.last_active_at.getTime() + IDLE_GRACE_MS);
|
|
113
|
+
if (rangeEnd <= rangeStart)
|
|
114
|
+
return 0;
|
|
115
|
+
return (rangeEnd - rangeStart) / (1000 * 60 * 60);
|
|
116
|
+
}
|
|
117
|
+
function pct(used, allowance) {
|
|
118
|
+
if (!Number.isFinite(allowance) || allowance <= 0)
|
|
119
|
+
return 0;
|
|
120
|
+
return Math.min(used / allowance * 100, 100);
|
|
121
|
+
}
|
|
122
|
+
async function getComputeUsage(db, accountId, plan, periodStart, now = new Date) {
|
|
123
|
+
const tenants = await db.selectFrom("tenants").select(["id", "cpus", "status", "created_at", "last_active_at"]).where("account_id", "=", accountId).where("status", "!=", "deleted").execute();
|
|
124
|
+
let totalHours = 0;
|
|
125
|
+
for (const t of tenants) {
|
|
126
|
+
const hours = computeActiveHours(periodStart, now, {
|
|
127
|
+
created_at: t.created_at,
|
|
128
|
+
last_active_at: t.last_active_at,
|
|
129
|
+
status: String(t.status)
|
|
130
|
+
});
|
|
131
|
+
totalHours += hours * Number(t.cpus);
|
|
132
|
+
}
|
|
133
|
+
const allowance = getComputeAllowanceHours(plan);
|
|
134
|
+
const sparkline = [];
|
|
135
|
+
for (const day of lastNDays(14, now)) {
|
|
136
|
+
const dayStart = new Date(`${day}T00:00:00.000Z`);
|
|
137
|
+
const dayEnd = new Date(`${day}T23:59:59.999Z`);
|
|
138
|
+
let dayHours = 0;
|
|
139
|
+
for (const t of tenants) {
|
|
140
|
+
const hours = computeActiveHours(dayStart, dayEnd, {
|
|
141
|
+
created_at: t.created_at,
|
|
142
|
+
last_active_at: t.last_active_at,
|
|
143
|
+
status: String(t.status)
|
|
144
|
+
});
|
|
145
|
+
dayHours += Math.min(hours, 24) * Number(t.cpus);
|
|
146
|
+
}
|
|
147
|
+
sparkline.push({ day, value: dayHours });
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
usedHours: totalHours,
|
|
151
|
+
allowanceHours: allowance,
|
|
152
|
+
pct: pct(totalHours, allowance),
|
|
153
|
+
sparkline
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
async function getStorageUsage(db, accountId, plan, now = new Date) {
|
|
157
|
+
const current = await db.selectFrom("tenants").select(sql`COALESCE(SUM(storage_used_mb), 0)`.as("mb")).where("account_id", "=", accountId).where("status", "!=", "deleted").executeTakeFirst();
|
|
158
|
+
const usedBytes = Number(current?.mb ?? 0) * BYTES_PER_MB;
|
|
159
|
+
const allowance = getStorageAllowanceBytes(plan);
|
|
160
|
+
const sparkline = [];
|
|
161
|
+
for (const day of lastNDays(14, now)) {
|
|
162
|
+
sparkline.push({ day, value: Number(current?.mb ?? 0) });
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
usedBytes,
|
|
166
|
+
allowanceBytes: allowance,
|
|
167
|
+
pct: pct(usedBytes, allowance),
|
|
168
|
+
sparkline
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
async function getAiUsage(_db, _accountId, plan, _periodStart, now = new Date) {
|
|
172
|
+
const dailyCap = getAiCapForPlan(plan).evalsPerDay;
|
|
173
|
+
const sparkline = [];
|
|
174
|
+
for (const day of lastNDays(14, now))
|
|
175
|
+
sparkline.push({ day, value: 0 });
|
|
176
|
+
return { todayCount: 0, periodCount: 0, dailyCap, pct: 0, sparkline };
|
|
177
|
+
}
|
|
178
|
+
async function getProjectBreakdown(db, accountId, plan, periodStart, now = new Date) {
|
|
179
|
+
const tenants = await db.selectFrom("tenants").select([
|
|
180
|
+
"id",
|
|
181
|
+
"slug",
|
|
182
|
+
"status",
|
|
183
|
+
"cpus",
|
|
184
|
+
"storage_used_mb",
|
|
185
|
+
"created_at",
|
|
186
|
+
"last_active_at"
|
|
187
|
+
]).where("account_id", "=", accountId).where("status", "!=", "deleted").orderBy("created_at", "desc").execute();
|
|
188
|
+
if (tenants.length === 0)
|
|
189
|
+
return [];
|
|
190
|
+
const aiByTenant = new Map;
|
|
191
|
+
const computeAllowance = getComputeAllowanceHours(plan);
|
|
192
|
+
const storageAllowance = getStorageAllowanceBytes(plan);
|
|
193
|
+
const aiDailyCap = getAiCapForPlan(plan).evalsPerDay;
|
|
194
|
+
return tenants.map((t) => {
|
|
195
|
+
const hours = computeActiveHours(periodStart, now, {
|
|
196
|
+
created_at: t.created_at,
|
|
197
|
+
last_active_at: t.last_active_at,
|
|
198
|
+
status: String(t.status)
|
|
199
|
+
}) * Number(t.cpus);
|
|
200
|
+
const bytes = Number(t.storage_used_mb ?? 0) * BYTES_PER_MB;
|
|
201
|
+
const todayAi = aiByTenant.get(t.id) ?? 0;
|
|
202
|
+
return {
|
|
203
|
+
id: t.id,
|
|
204
|
+
slug: t.slug,
|
|
205
|
+
name: t.slug,
|
|
206
|
+
status: String(t.status),
|
|
207
|
+
subgraphCount: 0,
|
|
208
|
+
compute: { hours, pct: pct(hours, computeAllowance) },
|
|
209
|
+
storage: { bytes, pct: pct(bytes, storageAllowance) },
|
|
210
|
+
aiEvals: { todayCount: todayAi, pct: pct(todayAi, aiDailyCap) }
|
|
211
|
+
};
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
export {
|
|
215
|
+
getStorageUsage,
|
|
216
|
+
getProjectBreakdown,
|
|
217
|
+
getComputeUsage,
|
|
218
|
+
getAiUsage
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
//# debugId=D94D306CAF5E896064756E2164756E21
|
|
222
|
+
//# sourceMappingURL=account-usage.js.map
|