@launchframe/mcp 1.1.2 → 1.1.4
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.
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
# Database Schema
|
|
2
|
+
|
|
3
|
+
## Tables & Columns
|
|
4
|
+
|
|
5
|
+
### Auth
|
|
6
|
+
|
|
7
|
+
#### `users`
|
|
8
|
+
| Column | Type | Nullable | Default |
|
|
9
|
+
|--------|------|----------|---------|
|
|
10
|
+
| id | integer (PK, serial) | NO | nextval |
|
|
11
|
+
| name | varchar | YES | |
|
|
12
|
+
| email | varchar | NO | |
|
|
13
|
+
| email_verified | boolean | NO | false |
|
|
14
|
+
| image | varchar | YES | |
|
|
15
|
+
| role | varchar | NO | 'business_user' |
|
|
16
|
+
| is_active | boolean | NO | true |
|
|
17
|
+
| created_at | timestamp | NO | CURRENT_TIMESTAMP |
|
|
18
|
+
| updated_at | timestamp | NO | CURRENT_TIMESTAMP |
|
|
19
|
+
|
|
20
|
+
Roles: `business_user`, `superadmin`, `customer` (B2B2C variant)
|
|
21
|
+
|
|
22
|
+
#### `sessions`
|
|
23
|
+
| Column | Type | Nullable | Default |
|
|
24
|
+
|--------|------|----------|---------|
|
|
25
|
+
| id | uuid (PK) | NO | |
|
|
26
|
+
| user_id | integer (FK → users.id) | NO | |
|
|
27
|
+
| token | varchar | NO | |
|
|
28
|
+
| expires_at | timestamp | NO | |
|
|
29
|
+
| ip_address | varchar | YES | |
|
|
30
|
+
| user_agent | text | YES | |
|
|
31
|
+
| created_at | timestamp | NO | now() |
|
|
32
|
+
| updated_at | timestamp | NO | now() |
|
|
33
|
+
|
|
34
|
+
#### `accounts`
|
|
35
|
+
| Column | Type | Nullable | Default |
|
|
36
|
+
|--------|------|----------|---------|
|
|
37
|
+
| id | uuid (PK) | NO | |
|
|
38
|
+
| user_id | integer (FK → users.id) | NO | |
|
|
39
|
+
| account_id | varchar | NO | |
|
|
40
|
+
| provider_id | varchar | NO | |
|
|
41
|
+
| access_token | text | YES | |
|
|
42
|
+
| refresh_token | text | YES | |
|
|
43
|
+
| access_token_expires_at | timestamp | YES | |
|
|
44
|
+
| refresh_token_expires_at | timestamp | YES | |
|
|
45
|
+
| scope | text | YES | |
|
|
46
|
+
| id_token | text | YES | |
|
|
47
|
+
| password | text | YES | |
|
|
48
|
+
| created_at | timestamp | NO | now() |
|
|
49
|
+
| updated_at | timestamp | NO | now() |
|
|
50
|
+
|
|
51
|
+
#### `verification`
|
|
52
|
+
| Column | Type | Nullable |
|
|
53
|
+
|--------|------|----------|
|
|
54
|
+
| id | uuid (PK) | NO |
|
|
55
|
+
| identifier | text | NO |
|
|
56
|
+
| value | text | NO |
|
|
57
|
+
| expires_at | timestamp | NO |
|
|
58
|
+
| created_at | timestamp | NO |
|
|
59
|
+
| updated_at | timestamp | NO |
|
|
60
|
+
|
|
61
|
+
#### `oauth_tokens`
|
|
62
|
+
| Column | Type | Nullable | Default |
|
|
63
|
+
|--------|------|----------|---------|
|
|
64
|
+
| id | integer (PK, serial) | NO | nextval |
|
|
65
|
+
| token_type | text | NO | |
|
|
66
|
+
| user_id | integer (FK → users.id) | NO | |
|
|
67
|
+
| access_token | text | NO | |
|
|
68
|
+
| refresh_token | text | NO | |
|
|
69
|
+
| expires_at | timestamp | NO | |
|
|
70
|
+
| created_at | timestamp | NO | CURRENT_TIMESTAMP |
|
|
71
|
+
| updated_at | timestamp | NO | CURRENT_TIMESTAMP |
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
### Subscriptions
|
|
76
|
+
|
|
77
|
+
#### `subscription_plans`
|
|
78
|
+
| Column | Type | Nullable | Default |
|
|
79
|
+
|--------|------|----------|---------|
|
|
80
|
+
| id | integer (PK, serial) | NO | nextval |
|
|
81
|
+
| name | varchar | NO | |
|
|
82
|
+
| code | varchar | NO | |
|
|
83
|
+
| description | text | YES | |
|
|
84
|
+
| price | numeric | NO | |
|
|
85
|
+
| billing_interval | varchar | NO | |
|
|
86
|
+
| trial_period_unit | varchar | YES | |
|
|
87
|
+
| trial_period_value | integer | YES | |
|
|
88
|
+
| features | jsonb | YES | |
|
|
89
|
+
| polar_product_id | varchar | YES | |
|
|
90
|
+
| polar_price_id | varchar | YES | |
|
|
91
|
+
| monthly_credits | integer | YES | |
|
|
92
|
+
| overage_rate | numeric | YES | |
|
|
93
|
+
| is_active | boolean | NO | true |
|
|
94
|
+
| sort_order | integer | NO | 0 |
|
|
95
|
+
| created_at | timestamp | NO | CURRENT_TIMESTAMP |
|
|
96
|
+
| updated_at | timestamp | NO | CURRENT_TIMESTAMP |
|
|
97
|
+
|
|
98
|
+
#### `user_subscriptions`
|
|
99
|
+
| Column | Type | Nullable | Default |
|
|
100
|
+
|--------|------|----------|---------|
|
|
101
|
+
| id | integer (PK, serial) | NO | nextval |
|
|
102
|
+
| user_id | integer (FK → users.id) | NO | |
|
|
103
|
+
| plan_id | integer (FK → subscription_plans.id) | NO | |
|
|
104
|
+
| status | varchar | NO | |
|
|
105
|
+
| current_period_start | timestamp | YES | |
|
|
106
|
+
| current_period_end | timestamp | YES | |
|
|
107
|
+
| canceled_at | timestamp | YES | |
|
|
108
|
+
| payment_provider | varchar | YES | 'paypal' |
|
|
109
|
+
| provider_subscription_id | varchar | YES | |
|
|
110
|
+
| provider_order_id | varchar | YES | |
|
|
111
|
+
| trial_end | timestamp | YES | |
|
|
112
|
+
| cancel_at_period_end | boolean | NO | false |
|
|
113
|
+
| created_at | timestamp | NO | CURRENT_TIMESTAMP |
|
|
114
|
+
| updated_at | timestamp | NO | CURRENT_TIMESTAMP |
|
|
115
|
+
| deleted_at | timestamp | YES | |
|
|
116
|
+
|
|
117
|
+
Status values: `active`, `trialing`, `canceled`, `past_due`, `incomplete`
|
|
118
|
+
|
|
119
|
+
#### `subscription_payments`
|
|
120
|
+
| Column | Type | Nullable | Default |
|
|
121
|
+
|--------|------|----------|---------|
|
|
122
|
+
| id | integer (PK, serial) | NO | nextval |
|
|
123
|
+
| user_id | integer (FK → users.id) | NO | |
|
|
124
|
+
| subscription_id | integer (FK → user_subscriptions.id) | NO | |
|
|
125
|
+
| paypal_order_id | varchar | NO | |
|
|
126
|
+
| amount | numeric | NO | |
|
|
127
|
+
| currency | varchar | NO | |
|
|
128
|
+
| status | varchar | NO | 'CREATED' |
|
|
129
|
+
| billing_period_start | timestamp | NO | |
|
|
130
|
+
| billing_period_end | timestamp | NO | |
|
|
131
|
+
| created_at | timestamp | NO | CURRENT_TIMESTAMP |
|
|
132
|
+
| updated_at | timestamp | NO | CURRENT_TIMESTAMP |
|
|
133
|
+
|
|
134
|
+
#### `user_subscription_logs`
|
|
135
|
+
| Column | Type | Nullable |
|
|
136
|
+
|--------|------|----------|
|
|
137
|
+
| id | integer (PK, serial) | NO |
|
|
138
|
+
| subscription_id | integer (FK → user_subscriptions.id) | NO |
|
|
139
|
+
| event | varchar | NO |
|
|
140
|
+
| metadata | jsonb | YES |
|
|
141
|
+
| previous_status | varchar | YES |
|
|
142
|
+
| new_status | varchar | YES |
|
|
143
|
+
| previous_plan | varchar | YES |
|
|
144
|
+
| new_plan | varchar | YES |
|
|
145
|
+
| description | text | YES |
|
|
146
|
+
| created_at | timestamp | NO |
|
|
147
|
+
|
|
148
|
+
#### `subscription_plan_features`
|
|
149
|
+
| Column | Type | Nullable | Default |
|
|
150
|
+
|--------|------|----------|---------|
|
|
151
|
+
| id | integer (PK, serial) | NO | nextval |
|
|
152
|
+
| name | varchar | NO | |
|
|
153
|
+
| code | varchar | NO | |
|
|
154
|
+
| description | text | YES | |
|
|
155
|
+
| feature_type | varchar | NO | |
|
|
156
|
+
| default_value | jsonb | YES | |
|
|
157
|
+
| template | text | YES | |
|
|
158
|
+
| is_active | boolean | NO | true |
|
|
159
|
+
| sort_order | integer | NO | 0 |
|
|
160
|
+
| created_at | timestamp | NO | CURRENT_TIMESTAMP |
|
|
161
|
+
| updated_at | timestamp | NO | CURRENT_TIMESTAMP |
|
|
162
|
+
|
|
163
|
+
#### `subscription_plan_feature_values`
|
|
164
|
+
| Column | Type | Nullable |
|
|
165
|
+
|--------|------|----------|
|
|
166
|
+
| id | integer (PK, serial) | NO |
|
|
167
|
+
| subscription_plan_id | integer (FK → subscription_plans.id) | NO |
|
|
168
|
+
| feature_id | integer (FK → subscription_plan_features.id) | NO |
|
|
169
|
+
| value | jsonb | NO |
|
|
170
|
+
| created_at | timestamp | NO |
|
|
171
|
+
| updated_at | timestamp | NO |
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
### Credits
|
|
176
|
+
|
|
177
|
+
#### `user_credits`
|
|
178
|
+
| Column | Type | Nullable | Default |
|
|
179
|
+
|--------|------|----------|---------|
|
|
180
|
+
| id | integer (PK, serial) | NO | nextval |
|
|
181
|
+
| user_id | integer (FK → users.id) | NO | |
|
|
182
|
+
| balance | integer | NO | 0 |
|
|
183
|
+
| included_credits_used | integer | NO | 0 |
|
|
184
|
+
| overage_credits_used | integer | NO | 0 |
|
|
185
|
+
| created_at | timestamp | NO | now() |
|
|
186
|
+
| updated_at | timestamp | NO | now() |
|
|
187
|
+
|
|
188
|
+
#### `credit_transactions`
|
|
189
|
+
| Column | Type | Nullable |
|
|
190
|
+
|--------|------|----------|
|
|
191
|
+
| id | integer (PK, serial) | NO |
|
|
192
|
+
| user_id | integer (FK → users.id) | NO |
|
|
193
|
+
| amount | integer | NO |
|
|
194
|
+
| type | enum (credit_transaction_type) | NO |
|
|
195
|
+
| description | text | YES |
|
|
196
|
+
| reference_id | varchar | YES |
|
|
197
|
+
| created_at | timestamp | NO |
|
|
198
|
+
|
|
199
|
+
Transaction types: `purchase`, `deduction`, `grant`, `refund`, `expiry`
|
|
200
|
+
|
|
201
|
+
#### `credit_packs`
|
|
202
|
+
| Column | Type | Nullable | Default |
|
|
203
|
+
|--------|------|----------|---------|
|
|
204
|
+
| id | integer (PK, serial) | NO | nextval |
|
|
205
|
+
| name | varchar(255) | NO | |
|
|
206
|
+
| credits | integer | NO | |
|
|
207
|
+
| price | numeric | NO | |
|
|
208
|
+
| polar_product_id | varchar(255) | NO | |
|
|
209
|
+
| polar_price_id | varchar(255) | YES | |
|
|
210
|
+
| is_active | boolean | NO | true |
|
|
211
|
+
| expiry_days | integer | YES | |
|
|
212
|
+
| created_at | timestamp | NO | now() |
|
|
213
|
+
| updated_at | timestamp | NO | now() |
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
### Payments
|
|
218
|
+
|
|
219
|
+
#### `payment_transactions`
|
|
220
|
+
| Column | Type | Nullable | Default |
|
|
221
|
+
|--------|------|----------|---------|
|
|
222
|
+
| id | integer (PK, serial) | NO | nextval |
|
|
223
|
+
| user_id | integer (FK → users.id) | NO | |
|
|
224
|
+
| paypal_order_id | varchar | NO | |
|
|
225
|
+
| amount | numeric | NO | |
|
|
226
|
+
| currency | varchar(3) | NO | |
|
|
227
|
+
| credits | integer | NO | |
|
|
228
|
+
| status | varchar | NO | 'CREATED' |
|
|
229
|
+
| description | text | YES | |
|
|
230
|
+
| created_at | timestamp | NO | CURRENT_TIMESTAMP |
|
|
231
|
+
| updated_at | timestamp | NO | CURRENT_TIMESTAMP |
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
### API / Webhooks
|
|
236
|
+
|
|
237
|
+
#### `api_keys`
|
|
238
|
+
| Column | Type | Nullable | Default |
|
|
239
|
+
|--------|------|----------|---------|
|
|
240
|
+
| id | integer (PK, serial) | NO | nextval |
|
|
241
|
+
| user_id | integer (FK → users.id) | NO | |
|
|
242
|
+
| key | varchar | NO | |
|
|
243
|
+
| name | varchar | NO | |
|
|
244
|
+
| is_active | boolean | NO | true |
|
|
245
|
+
| permissions | jsonb | YES | |
|
|
246
|
+
| requests_count | bigint | NO | 0 |
|
|
247
|
+
| last_used_at | timestamp | YES | |
|
|
248
|
+
| created_at | timestamp | NO | now() |
|
|
249
|
+
|
|
250
|
+
#### `webhooks`
|
|
251
|
+
| Column | Type | Nullable | Default |
|
|
252
|
+
|--------|------|----------|---------|
|
|
253
|
+
| id | integer (PK, serial) | NO | nextval |
|
|
254
|
+
| user_id | integer (FK → users.id) | NO | |
|
|
255
|
+
| uuid | uuid | NO | uuid_generate_v4() |
|
|
256
|
+
| signing_secret | varchar | NO | |
|
|
257
|
+
| url | varchar | NO | |
|
|
258
|
+
| created_at | timestamp | NO | now() |
|
|
259
|
+
| updated_at | timestamp | NO | now() |
|
|
260
|
+
|
|
261
|
+
#### `webhook_logs`
|
|
262
|
+
| Column | Type | Nullable | Default |
|
|
263
|
+
|--------|------|----------|---------|
|
|
264
|
+
| id | uuid (PK) | NO | uuid_generate_v4() |
|
|
265
|
+
| provider | varchar(50) | NO | |
|
|
266
|
+
| event_type | varchar(255) | NO | |
|
|
267
|
+
| webhook_id | varchar(255) | YES | |
|
|
268
|
+
| payload | jsonb | NO | |
|
|
269
|
+
| headers | jsonb | YES | |
|
|
270
|
+
| processed | boolean | NO | false |
|
|
271
|
+
| processed_at | timestamp | YES | |
|
|
272
|
+
| processing_error | text | YES | |
|
|
273
|
+
| retry_count | integer | NO | 0 |
|
|
274
|
+
| created_at | timestamp | NO | CURRENT_TIMESTAMP |
|
|
275
|
+
| updated_at | timestamp | NO | CURRENT_TIMESTAMP |
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
### Projects / Multi-Tenancy
|
|
280
|
+
|
|
281
|
+
#### `projects`
|
|
282
|
+
| Column | Type | Nullable | Default |
|
|
283
|
+
|--------|------|----------|---------|
|
|
284
|
+
| id | integer (PK, serial) | NO | nextval |
|
|
285
|
+
| uuid | uuid | YES | uuid_generate_v4() |
|
|
286
|
+
| user_id | integer (FK → users.id) | NO | |
|
|
287
|
+
| title | varchar | NO | |
|
|
288
|
+
| slug | varchar | NO | |
|
|
289
|
+
| description | text | YES | |
|
|
290
|
+
| created_at | timestamp | NO | now() |
|
|
291
|
+
| updated_at | timestamp | NO | now() |
|
|
292
|
+
|
|
293
|
+
#### `project_domain`
|
|
294
|
+
| Column | Type | Nullable | Default |
|
|
295
|
+
|--------|------|----------|---------|
|
|
296
|
+
| id | integer (PK, serial) | NO | nextval |
|
|
297
|
+
| project_id | integer (FK → projects.id) | NO | |
|
|
298
|
+
| domain | varchar | NO | |
|
|
299
|
+
| added_to_cloudflare | boolean | NO | false |
|
|
300
|
+
| dns_verification_status | enum | NO | 'pending' |
|
|
301
|
+
| created_at | timestamp | NO | CURRENT_TIMESTAMP |
|
|
302
|
+
| updated_at | timestamp | NO | CURRENT_TIMESTAMP |
|
|
303
|
+
|
|
304
|
+
DNS status values: `pending`, `verified`, `failed`
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
### Admin
|
|
309
|
+
|
|
310
|
+
#### `admin_settings`
|
|
311
|
+
| Column | Type | Nullable |
|
|
312
|
+
|--------|------|----------|
|
|
313
|
+
| key | varchar (PK) | NO |
|
|
314
|
+
| value | varchar | NO |
|
|
315
|
+
| created_at | timestamp | NO |
|
|
316
|
+
| updated_at | timestamp | NO |
|
|
317
|
+
|
|
318
|
+
#### `user_settings`
|
|
319
|
+
| Column | Type | Nullable | Default |
|
|
320
|
+
|--------|------|----------|---------|
|
|
321
|
+
| id | integer (PK, serial) | NO | nextval |
|
|
322
|
+
| user_id | integer (FK → users.id) | NO | |
|
|
323
|
+
| allow_overage | boolean | NO | true |
|
|
324
|
+
| max_overage_credits | integer | YES | |
|
|
325
|
+
| theme_mode | varchar(20) | NO | 'light' |
|
|
326
|
+
| density | varchar(20) | NO | 'comfortable' |
|
|
327
|
+
| created_at | timestamp | NO | now() |
|
|
328
|
+
| updated_at | timestamp | NO | now() |
|
|
329
|
+
|
|
330
|
+
#### `user_businesses` (B2B2C variant)
|
|
331
|
+
| Column | Type | Nullable |
|
|
332
|
+
|--------|------|----------|
|
|
333
|
+
| id | integer (PK, serial) | NO |
|
|
334
|
+
| user_id | integer (FK → users.id) | NO |
|
|
335
|
+
| business_id | integer | NO |
|
|
336
|
+
| created_at | timestamp | NO |
|
|
337
|
+
| updated_at | timestamp | NO |
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
## Common Questions → SQL Queries
|
|
342
|
+
|
|
343
|
+
### Users & Auth
|
|
344
|
+
|
|
345
|
+
```sql
|
|
346
|
+
-- How many users are there?
|
|
347
|
+
SELECT COUNT(*) FROM users;
|
|
348
|
+
|
|
349
|
+
-- How many verified users?
|
|
350
|
+
SELECT COUNT(*) FROM users WHERE email_verified = true;
|
|
351
|
+
|
|
352
|
+
-- How many active users?
|
|
353
|
+
SELECT COUNT(*) FROM users WHERE is_active = true;
|
|
354
|
+
|
|
355
|
+
-- List all users (recent first)
|
|
356
|
+
SELECT id, name, email, role, email_verified, created_at FROM users ORDER BY created_at DESC LIMIT 20;
|
|
357
|
+
|
|
358
|
+
-- How many active sessions?
|
|
359
|
+
SELECT COUNT(*) FROM sessions WHERE expires_at > NOW();
|
|
360
|
+
|
|
361
|
+
-- How many superadmins?
|
|
362
|
+
SELECT COUNT(*) FROM users WHERE role = 'superadmin';
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### Subscriptions
|
|
366
|
+
|
|
367
|
+
```sql
|
|
368
|
+
-- Which subscription plans exist?
|
|
369
|
+
SELECT name, code, price, billing_interval, is_active FROM subscription_plans ORDER BY sort_order;
|
|
370
|
+
|
|
371
|
+
-- What's the most expensive subscription plan?
|
|
372
|
+
SELECT name, price FROM subscription_plans ORDER BY price DESC LIMIT 1;
|
|
373
|
+
|
|
374
|
+
-- How many active subscriptions?
|
|
375
|
+
SELECT COUNT(*) FROM user_subscriptions WHERE status = 'active' AND deleted_at IS NULL;
|
|
376
|
+
|
|
377
|
+
-- Subscriptions by status
|
|
378
|
+
SELECT status, COUNT(*) FROM user_subscriptions WHERE deleted_at IS NULL GROUP BY status;
|
|
379
|
+
|
|
380
|
+
-- Which users have active subscriptions?
|
|
381
|
+
SELECT u.email, sp.name AS plan, us.status, us.current_period_end
|
|
382
|
+
FROM user_subscriptions us
|
|
383
|
+
JOIN users u ON u.id = us.user_id
|
|
384
|
+
JOIN subscription_plans sp ON sp.id = us.plan_id
|
|
385
|
+
WHERE us.status = 'active' AND us.deleted_at IS NULL
|
|
386
|
+
ORDER BY us.created_at DESC;
|
|
387
|
+
|
|
388
|
+
-- Recent subscription payments
|
|
389
|
+
SELECT * FROM subscription_payments ORDER BY created_at DESC LIMIT 10;
|
|
390
|
+
|
|
391
|
+
-- Subscription plan feature values for a plan
|
|
392
|
+
SELECT sp.name AS plan, spf.code AS feature, spfv.value
|
|
393
|
+
FROM subscription_plan_feature_values spfv
|
|
394
|
+
JOIN subscription_plans sp ON sp.id = spfv.subscription_plan_id
|
|
395
|
+
JOIN subscription_plan_features spf ON spf.id = spfv.feature_id
|
|
396
|
+
ORDER BY sp.name, spf.code;
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### Credits
|
|
400
|
+
|
|
401
|
+
```sql
|
|
402
|
+
-- Credit balance totals (sum and average)
|
|
403
|
+
SELECT SUM(balance), AVG(balance), MIN(balance), MAX(balance) FROM user_credits;
|
|
404
|
+
|
|
405
|
+
-- Users with the most credits
|
|
406
|
+
SELECT u.email, uc.balance FROM user_credits uc JOIN users u ON u.id = uc.user_id ORDER BY uc.balance DESC LIMIT 10;
|
|
407
|
+
|
|
408
|
+
-- Recent credit transactions
|
|
409
|
+
SELECT ct.type, ct.amount, ct.description, u.email, ct.created_at
|
|
410
|
+
FROM credit_transactions ct
|
|
411
|
+
JOIN users u ON u.id = ct.user_id
|
|
412
|
+
ORDER BY ct.created_at DESC LIMIT 20;
|
|
413
|
+
|
|
414
|
+
-- Credit transactions by type
|
|
415
|
+
SELECT type, COUNT(*), SUM(amount) FROM credit_transactions GROUP BY type;
|
|
416
|
+
|
|
417
|
+
-- Which credit packs are available?
|
|
418
|
+
SELECT name, credits, price, is_active FROM credit_packs ORDER BY price;
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
### Payments
|
|
422
|
+
|
|
423
|
+
```sql
|
|
424
|
+
-- Recent payments (credit pack purchases)
|
|
425
|
+
SELECT pt.amount, pt.currency, pt.credits, pt.status, u.email, pt.created_at
|
|
426
|
+
FROM payment_transactions pt
|
|
427
|
+
JOIN users u ON u.id = pt.user_id
|
|
428
|
+
ORDER BY pt.created_at DESC LIMIT 10;
|
|
429
|
+
|
|
430
|
+
-- Total revenue from credit packs
|
|
431
|
+
SELECT SUM(amount) AS total_revenue, COUNT(*) AS total_transactions
|
|
432
|
+
FROM payment_transactions WHERE status = 'COMPLETED';
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
### API & Webhooks
|
|
436
|
+
|
|
437
|
+
```sql
|
|
438
|
+
-- How many active API keys?
|
|
439
|
+
SELECT COUNT(*) FROM api_keys WHERE is_active = true;
|
|
440
|
+
|
|
441
|
+
-- Most used API keys
|
|
442
|
+
SELECT name, requests_count, last_used_at FROM api_keys WHERE is_active = true ORDER BY requests_count DESC LIMIT 10;
|
|
443
|
+
|
|
444
|
+
-- How many unprocessed webhooks?
|
|
445
|
+
SELECT COUNT(*) FROM webhook_logs WHERE processed = false;
|
|
446
|
+
|
|
447
|
+
-- Unprocessed webhook logs
|
|
448
|
+
SELECT provider, event_type, retry_count, created_at FROM webhook_logs WHERE processed = false ORDER BY created_at DESC;
|
|
449
|
+
|
|
450
|
+
-- Webhook logs with errors
|
|
451
|
+
SELECT provider, event_type, processing_error, retry_count FROM webhook_logs WHERE processing_error IS NOT NULL ORDER BY created_at DESC LIMIT 10;
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
### Projects
|
|
455
|
+
|
|
456
|
+
```sql
|
|
457
|
+
-- How many projects are there?
|
|
458
|
+
SELECT COUNT(*) FROM projects;
|
|
459
|
+
|
|
460
|
+
-- Projects per user
|
|
461
|
+
SELECT u.email, COUNT(p.id) AS project_count FROM projects p JOIN users u ON u.id = p.user_id GROUP BY u.email ORDER BY project_count DESC;
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
### Admin
|
|
465
|
+
|
|
466
|
+
```sql
|
|
467
|
+
-- All admin settings
|
|
468
|
+
SELECT key, value FROM admin_settings ORDER BY key;
|
|
469
|
+
|
|
470
|
+
-- Get a specific admin setting
|
|
471
|
+
SELECT value FROM admin_settings WHERE key = 'credits_strategy';
|
|
472
|
+
```
|
package/dist/server.js
CHANGED
|
@@ -10,6 +10,7 @@ import { registerEntityTools } from './tools/entities.js';
|
|
|
10
10
|
import { registerEnvTools } from './tools/env.js';
|
|
11
11
|
import { registerVariantTools } from './tools/variants.js';
|
|
12
12
|
import { registerCliTools } from './tools/cli.js';
|
|
13
|
+
import { registerDatabaseTools } from './tools/database.js';
|
|
13
14
|
export function createServer() {
|
|
14
15
|
const server = new McpServer({ name: 'launchframe-mcp', version: '1.0.0' });
|
|
15
16
|
registerAuthTools(server);
|
|
@@ -23,5 +24,6 @@ export function createServer() {
|
|
|
23
24
|
registerEnvTools(server);
|
|
24
25
|
registerVariantTools(server);
|
|
25
26
|
registerCliTools(server);
|
|
27
|
+
registerDatabaseTools(server);
|
|
26
28
|
return server;
|
|
27
29
|
}
|
package/dist/tools/cli.js
CHANGED
|
@@ -132,7 +132,7 @@ export function registerCliTools(server) {
|
|
|
132
132
|
return { content: [{ type: 'text', text: error.message }] };
|
|
133
133
|
}
|
|
134
134
|
});
|
|
135
|
-
server.tool('cli_database_query', 'Execute a SQL query against the local (or remote) database and return results. Use for SELECT queries, schema inspection, or data checks. When remote=true, will prompt for confirmation before touching production.', {
|
|
135
|
+
server.tool('cli_database_query', 'Execute a SQL query against the local (or remote) database and return results. Use for SELECT queries, schema inspection, or data checks. When remote=true, will prompt for confirmation before touching production. Call database_schema first if you need to know what tables/columns exist.', {
|
|
136
136
|
projectPath: z.string().describe('Absolute path to the LaunchFrame project root'),
|
|
137
137
|
sql: z.string().describe('SQL to execute (e.g., "SELECT * FROM users LIMIT 10;")'),
|
|
138
138
|
remote: z.boolean().optional().describe('If true, query the production database via SSH instead of local. Requires confirmation.'),
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { loadContent } from '../lib/content.js';
|
|
2
|
+
export function registerDatabaseTools(server) {
|
|
3
|
+
server.tool('database_schema', 'Returns the full database schema (all tables, columns, types, relations) plus ready-made SQL snippets for common questions like user counts, active sessions, subscription plans, credit balances, etc. Call this before running cli_database_query when the user asks a data question.', {}, async () => ({
|
|
4
|
+
content: [{ type: 'text', text: loadContent('database/schema.md') }],
|
|
5
|
+
}));
|
|
6
|
+
}
|