mcp-scraper 0.38.1 → 0.38.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 +1 -1
- package/dist/bin/api-server.cjs +718 -276
- package/dist/bin/api-server.cjs.map +1 -1
- package/dist/bin/api-server.js +3 -3
- package/dist/bin/mcp-scraper-cli.cjs +1 -1
- package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
- package/dist/bin/mcp-scraper-cli.js +1 -1
- package/dist/bin/mcp-scraper-install.cjs +1 -1
- package/dist/bin/mcp-scraper-install.cjs.map +1 -1
- package/dist/bin/mcp-scraper-install.js +1 -1
- package/dist/bin/mcp-stdio-server.cjs +25 -7
- package/dist/bin/mcp-stdio-server.cjs.map +1 -1
- package/dist/bin/mcp-stdio-server.js +5 -5
- package/dist/bin/paa-harvest.cjs +65 -4
- package/dist/bin/paa-harvest.cjs.map +1 -1
- package/dist/bin/paa-harvest.js +3 -3
- package/dist/{chunk-PWPUKR5U.js → chunk-AZRPG43B.js} +12 -3
- package/dist/chunk-AZRPG43B.js.map +1 -0
- package/dist/{chunk-C5UGV7RM.js → chunk-EGJKUB4Q.js} +3 -3
- package/dist/{chunk-C5UGV7RM.js.map → chunk-EGJKUB4Q.js.map} +1 -1
- package/dist/{chunk-WS2E7HA5.js → chunk-FRYT3ID4.js} +2 -2
- package/dist/{chunk-XKCZOPZN.js → chunk-N7KUTTCC.js} +235 -40
- package/dist/chunk-N7KUTTCC.js.map +1 -0
- package/dist/{chunk-BSD2Z5A6.js → chunk-NGM237OO.js} +66 -5
- package/dist/chunk-NGM237OO.js.map +1 -0
- package/dist/{chunk-YAW3AUTP.js → chunk-NKCCGADE.js} +23 -8
- package/dist/chunk-NKCCGADE.js.map +1 -0
- package/dist/{chunk-OLRRIA4H.js → chunk-SFRMFGQ6.js} +2 -2
- package/dist/{chunk-4YAFJWFG.js → chunk-YCI2PNCS.js} +3 -3
- package/dist/chunk-YODBNTTN.js +7 -0
- package/dist/chunk-YODBNTTN.js.map +1 -0
- package/dist/{db-JRFMBTRD.js → db-C5KVCOYT.js} +8 -4
- package/dist/{extract-bundle-DSFOHMAT.js → extract-bundle-KUBX6N6Z.js} +4 -4
- package/dist/index.cjs +65 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +3 -3
- package/dist/{location-data-repository-OBJYZEGE.js → location-data-repository-TTWF3OTM.js} +3 -3
- package/dist/{server-2UDB6PTC.js → server-5EX6XBIA.js} +312 -151
- package/dist/server-5EX6XBIA.js.map +1 -0
- package/dist/{site-extract-repository-2YJ33J5C.js → site-extract-repository-XSPJTCIL.js} +4 -4
- package/dist/{worker-ESF3HCNJ.js → worker-XCPU4YSN.js} +6 -6
- package/docs/mcp-tool-manifest.generated.json +66 -9
- package/package.json +1 -1
- package/dist/chunk-BSD2Z5A6.js.map +0 -1
- package/dist/chunk-FFBPWVWC.js +0 -7
- package/dist/chunk-FFBPWVWC.js.map +0 -1
- package/dist/chunk-PWPUKR5U.js.map +0 -1
- package/dist/chunk-XKCZOPZN.js.map +0 -1
- package/dist/chunk-YAW3AUTP.js.map +0 -1
- package/dist/server-2UDB6PTC.js.map +0 -1
- /package/dist/{chunk-WS2E7HA5.js.map → chunk-FRYT3ID4.js.map} +0 -0
- /package/dist/{chunk-OLRRIA4H.js.map → chunk-SFRMFGQ6.js.map} +0 -0
- /package/dist/{chunk-4YAFJWFG.js.map → chunk-YCI2PNCS.js.map} +0 -0
- /package/dist/{db-JRFMBTRD.js.map → db-C5KVCOYT.js.map} +0 -0
- /package/dist/{extract-bundle-DSFOHMAT.js.map → extract-bundle-KUBX6N6Z.js.map} +0 -0
- /package/dist/{location-data-repository-OBJYZEGE.js.map → location-data-repository-TTWF3OTM.js.map} +0 -0
- /package/dist/{site-extract-repository-2YJ33J5C.js.map → site-extract-repository-XSPJTCIL.js.map} +0 -0
- /package/dist/{worker-ESF3HCNJ.js.map → worker-XCPU4YSN.js.map} +0 -0
|
@@ -11,7 +11,7 @@ var DB_URL = process.env.TURSO_DATABASE_URL ?? "file:./paa-api.db";
|
|
|
11
11
|
var DB_TOKEN = process.env.TURSO_AUTH_TOKEN;
|
|
12
12
|
var _db = null;
|
|
13
13
|
var _rateLimitSchemaReady = false;
|
|
14
|
-
var CORE_SCHEMA_VERSION = "2026-07-28.
|
|
14
|
+
var CORE_SCHEMA_VERSION = "2026-07-28.3";
|
|
15
15
|
var CORE_SCHEMA_TABLES = [
|
|
16
16
|
"admin_credit_adjustment_events",
|
|
17
17
|
"admin_credit_adjustments",
|
|
@@ -23,6 +23,7 @@ var CORE_SCHEMA_TABLES = [
|
|
|
23
23
|
"browser_profile_labels",
|
|
24
24
|
"connected_account_billing",
|
|
25
25
|
"concurrency_locks",
|
|
26
|
+
"credit_lot_expirations",
|
|
26
27
|
"credit_lots",
|
|
27
28
|
"credit_lot_repairs",
|
|
28
29
|
"free_credit_refreshes",
|
|
@@ -91,6 +92,12 @@ var CORE_SCHEMA_INDEXES = [
|
|
|
91
92
|
"workflow_schedules_user_status",
|
|
92
93
|
"workflow_webhook_deliveries_run"
|
|
93
94
|
];
|
|
95
|
+
var CORE_SCHEMA_TRIGGERS = [
|
|
96
|
+
"credit_lots_bounds_insert",
|
|
97
|
+
"credit_lots_bounds_update",
|
|
98
|
+
"credit_lots_one_migration_insert",
|
|
99
|
+
"credit_lots_one_migration_update"
|
|
100
|
+
];
|
|
94
101
|
var CORE_SCHEMA_COLUMNS = {
|
|
95
102
|
credit_lots: ["never_expires"],
|
|
96
103
|
harvest_attempts: ["debug_json"],
|
|
@@ -108,6 +115,7 @@ var CORE_SCHEMA_COLUMNS = {
|
|
|
108
115
|
"next_settlement_at",
|
|
109
116
|
"settlement_error"
|
|
110
117
|
],
|
|
118
|
+
stripe_events: ["attempt_count", "claim_token", "last_error", "status", "updated_at"],
|
|
111
119
|
users: [
|
|
112
120
|
"balance_mc",
|
|
113
121
|
"concurrency_stripe_sub_id",
|
|
@@ -134,6 +142,7 @@ async function hasCurrentCoreSchema(db) {
|
|
|
134
142
|
const checks = [
|
|
135
143
|
`(SELECT COUNT(*) FROM sqlite_master WHERE type = 'table' AND name IN (${sqlStringList(CORE_SCHEMA_TABLES)})) = ${CORE_SCHEMA_TABLES.length}`,
|
|
136
144
|
`(SELECT COUNT(*) FROM sqlite_master WHERE type = 'index' AND name IN (${sqlStringList(CORE_SCHEMA_INDEXES)})) = ${CORE_SCHEMA_INDEXES.length}`,
|
|
145
|
+
`(SELECT COUNT(*) FROM sqlite_master WHERE type = 'trigger' AND name IN (${sqlStringList(CORE_SCHEMA_TRIGGERS)})) = ${CORE_SCHEMA_TRIGGERS.length}`,
|
|
137
146
|
...Object.entries(CORE_SCHEMA_COLUMNS).map(
|
|
138
147
|
([table, columns]) => `(SELECT COUNT(*) FROM pragma_table_info('${table}') WHERE name IN (${sqlStringList(columns)})) = ${columns.length}`
|
|
139
148
|
)
|
|
@@ -409,6 +418,61 @@ async function migrate() {
|
|
|
409
418
|
} catch {
|
|
410
419
|
}
|
|
411
420
|
await db.execute(`CREATE INDEX IF NOT EXISTS credit_lots_user_active ON credit_lots(user_id, expires_at, remaining_mc)`);
|
|
421
|
+
await db.execute(`
|
|
422
|
+
CREATE TABLE IF NOT EXISTS credit_lot_expirations (
|
|
423
|
+
lot_id INTEGER PRIMARY KEY REFERENCES credit_lots(id),
|
|
424
|
+
user_id INTEGER NOT NULL REFERENCES users(id),
|
|
425
|
+
amount_mc INTEGER NOT NULL,
|
|
426
|
+
claim_token TEXT NOT NULL UNIQUE,
|
|
427
|
+
expired_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
428
|
+
)
|
|
429
|
+
`);
|
|
430
|
+
await db.execute(`
|
|
431
|
+
CREATE TRIGGER IF NOT EXISTS credit_lots_bounds_insert
|
|
432
|
+
BEFORE INSERT ON credit_lots
|
|
433
|
+
WHEN NEW.amount_mc < 0
|
|
434
|
+
OR NEW.remaining_mc < 0
|
|
435
|
+
OR NEW.remaining_mc > NEW.amount_mc
|
|
436
|
+
BEGIN
|
|
437
|
+
SELECT RAISE(ABORT, 'invalid credit lot bounds');
|
|
438
|
+
END
|
|
439
|
+
`);
|
|
440
|
+
await db.execute(`
|
|
441
|
+
CREATE TRIGGER IF NOT EXISTS credit_lots_bounds_update
|
|
442
|
+
BEFORE UPDATE OF amount_mc, remaining_mc ON credit_lots
|
|
443
|
+
WHEN NEW.amount_mc < 0
|
|
444
|
+
OR NEW.remaining_mc < 0
|
|
445
|
+
OR NEW.remaining_mc > NEW.amount_mc
|
|
446
|
+
BEGIN
|
|
447
|
+
SELECT RAISE(ABORT, 'invalid credit lot bounds');
|
|
448
|
+
END
|
|
449
|
+
`);
|
|
450
|
+
await db.execute(`
|
|
451
|
+
CREATE TRIGGER IF NOT EXISTS credit_lots_one_migration_insert
|
|
452
|
+
BEFORE INSERT ON credit_lots
|
|
453
|
+
WHEN NEW.source = 'migration'
|
|
454
|
+
AND EXISTS (
|
|
455
|
+
SELECT 1 FROM credit_lots
|
|
456
|
+
WHERE user_id = NEW.user_id AND source = 'migration'
|
|
457
|
+
)
|
|
458
|
+
BEGIN
|
|
459
|
+
SELECT RAISE(ABORT, 'duplicate migration lot');
|
|
460
|
+
END
|
|
461
|
+
`);
|
|
462
|
+
await db.execute(`
|
|
463
|
+
CREATE TRIGGER IF NOT EXISTS credit_lots_one_migration_update
|
|
464
|
+
BEFORE UPDATE OF source, user_id ON credit_lots
|
|
465
|
+
WHEN NEW.source = 'migration'
|
|
466
|
+
AND EXISTS (
|
|
467
|
+
SELECT 1 FROM credit_lots
|
|
468
|
+
WHERE user_id = NEW.user_id
|
|
469
|
+
AND source = 'migration'
|
|
470
|
+
AND id != OLD.id
|
|
471
|
+
)
|
|
472
|
+
BEGIN
|
|
473
|
+
SELECT RAISE(ABORT, 'duplicate migration lot');
|
|
474
|
+
END
|
|
475
|
+
`);
|
|
412
476
|
await db.execute(`
|
|
413
477
|
CREATE TABLE IF NOT EXISTS credit_lot_repairs (
|
|
414
478
|
repair_id TEXT PRIMARY KEY,
|
|
@@ -798,10 +862,37 @@ async function migrate() {
|
|
|
798
862
|
await db.execute(`CREATE INDEX IF NOT EXISTS workflow_webhook_deliveries_run ON workflow_webhook_deliveries(run_id)`);
|
|
799
863
|
await db.execute(`
|
|
800
864
|
CREATE TABLE IF NOT EXISTS stripe_events (
|
|
801
|
-
event_id
|
|
802
|
-
|
|
865
|
+
event_id TEXT PRIMARY KEY,
|
|
866
|
+
status TEXT NOT NULL DEFAULT 'processed',
|
|
867
|
+
attempt_count INTEGER NOT NULL DEFAULT 1,
|
|
868
|
+
claim_token TEXT,
|
|
869
|
+
last_error TEXT,
|
|
870
|
+
processed_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
871
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
803
872
|
)
|
|
804
873
|
`);
|
|
874
|
+
for (const col of [
|
|
875
|
+
`status TEXT NOT NULL DEFAULT 'processed'`,
|
|
876
|
+
"attempt_count INTEGER NOT NULL DEFAULT 1",
|
|
877
|
+
"claim_token TEXT",
|
|
878
|
+
"last_error TEXT",
|
|
879
|
+
"updated_at TEXT"
|
|
880
|
+
]) {
|
|
881
|
+
try {
|
|
882
|
+
await db.execute(`ALTER TABLE stripe_events ADD COLUMN ${col}`);
|
|
883
|
+
} catch {
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
await db.execute(`
|
|
887
|
+
UPDATE stripe_events
|
|
888
|
+
SET updated_at = COALESCE(updated_at, processed_at),
|
|
889
|
+
status = COALESCE(status, 'processed'),
|
|
890
|
+
attempt_count = MAX(1, COALESCE(attempt_count, 1))
|
|
891
|
+
WHERE updated_at IS NULL
|
|
892
|
+
OR status IS NULL
|
|
893
|
+
OR attempt_count IS NULL
|
|
894
|
+
OR attempt_count < 1
|
|
895
|
+
`);
|
|
805
896
|
await db.execute(`
|
|
806
897
|
CREATE TABLE IF NOT EXISTS oauth_clients (
|
|
807
898
|
client_id TEXT PRIMARY KEY,
|
|
@@ -967,16 +1058,60 @@ async function rotateRefresh(oldToken, next) {
|
|
|
967
1058
|
args: [next.refresh_token, (/* @__PURE__ */ new Date()).toISOString(), oldToken]
|
|
968
1059
|
});
|
|
969
1060
|
}
|
|
970
|
-
async function
|
|
971
|
-
const
|
|
972
|
-
|
|
1061
|
+
async function claimStripeEvent(eventId) {
|
|
1062
|
+
const token = randomUUID();
|
|
1063
|
+
const claimed = await getDb().execute({
|
|
1064
|
+
sql: `INSERT INTO stripe_events
|
|
1065
|
+
(event_id, status, attempt_count, claim_token, last_error, processed_at, updated_at)
|
|
1066
|
+
VALUES (?, 'processing', 1, ?, NULL, datetime('now'), datetime('now'))
|
|
1067
|
+
ON CONFLICT(event_id) DO UPDATE SET
|
|
1068
|
+
status = 'processing',
|
|
1069
|
+
attempt_count = stripe_events.attempt_count + 1,
|
|
1070
|
+
claim_token = excluded.claim_token,
|
|
1071
|
+
last_error = NULL,
|
|
1072
|
+
updated_at = datetime('now')
|
|
1073
|
+
WHERE stripe_events.status = 'failed'
|
|
1074
|
+
OR (
|
|
1075
|
+
stripe_events.status = 'processing'
|
|
1076
|
+
AND stripe_events.updated_at <= datetime('now', '-10 minutes')
|
|
1077
|
+
)`,
|
|
1078
|
+
args: [eventId, token]
|
|
1079
|
+
});
|
|
1080
|
+
if (claimed.rowsAffected > 0) return { state: "claimed", token };
|
|
1081
|
+
const current = await getDb().execute({
|
|
1082
|
+
sql: "SELECT status FROM stripe_events WHERE event_id = ? LIMIT 1",
|
|
973
1083
|
args: [eventId]
|
|
974
1084
|
});
|
|
975
|
-
return
|
|
1085
|
+
return { state: String(current.rows[0]?.status) === "processed" ? "processed" : "processing" };
|
|
1086
|
+
}
|
|
1087
|
+
async function completeStripeEvent(eventId, token) {
|
|
1088
|
+
const result = await getDb().execute({
|
|
1089
|
+
sql: `UPDATE stripe_events
|
|
1090
|
+
SET status = 'processed',
|
|
1091
|
+
claim_token = NULL,
|
|
1092
|
+
last_error = NULL,
|
|
1093
|
+
processed_at = datetime('now'),
|
|
1094
|
+
updated_at = datetime('now')
|
|
1095
|
+
WHERE event_id = ? AND status = 'processing' AND claim_token = ?`,
|
|
1096
|
+
args: [eventId, token]
|
|
1097
|
+
});
|
|
1098
|
+
return result.rowsAffected === 1;
|
|
1099
|
+
}
|
|
1100
|
+
async function failStripeEvent(eventId, token, error) {
|
|
1101
|
+
const result = await getDb().execute({
|
|
1102
|
+
sql: `UPDATE stripe_events
|
|
1103
|
+
SET status = 'failed',
|
|
1104
|
+
claim_token = NULL,
|
|
1105
|
+
last_error = ?,
|
|
1106
|
+
updated_at = datetime('now')
|
|
1107
|
+
WHERE event_id = ? AND status = 'processing' AND claim_token = ?`,
|
|
1108
|
+
args: [error.slice(0, 500), eventId, token]
|
|
1109
|
+
});
|
|
1110
|
+
return result.rowsAffected === 1;
|
|
976
1111
|
}
|
|
977
1112
|
async function stripeEventAlreadyProcessed(eventId) {
|
|
978
1113
|
const res = await getDb().execute({
|
|
979
|
-
sql:
|
|
1114
|
+
sql: `SELECT 1 FROM stripe_events WHERE event_id = ? AND status = 'processed' LIMIT 1`,
|
|
980
1115
|
args: [eventId]
|
|
981
1116
|
});
|
|
982
1117
|
return res.rows.length > 0;
|
|
@@ -1981,23 +2116,64 @@ async function ensureMigrated(userId) {
|
|
|
1981
2116
|
async function expireOldLots() {
|
|
1982
2117
|
const db = getDb();
|
|
1983
2118
|
const lots = await db.execute({
|
|
1984
|
-
sql: `SELECT id
|
|
2119
|
+
sql: `SELECT id
|
|
2120
|
+
FROM credit_lots
|
|
2121
|
+
WHERE remaining_mc > 0
|
|
2122
|
+
AND never_expires = 0
|
|
2123
|
+
AND expires_at <= datetime('now')
|
|
2124
|
+
LIMIT 500`
|
|
1985
2125
|
});
|
|
1986
2126
|
if (lots.rows.length === 0) return { expired_lots: 0, expired_mc: 0 };
|
|
1987
|
-
|
|
1988
|
-
const users = /* @__PURE__ */ new Set();
|
|
2127
|
+
const claims = [];
|
|
1989
2128
|
const stmts = [];
|
|
1990
2129
|
for (const lot of lots.rows) {
|
|
1991
|
-
const
|
|
1992
|
-
const
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
2130
|
+
const lotId = Number(lot.id);
|
|
2131
|
+
const token = randomUUID();
|
|
2132
|
+
claims.push({ token, insertResultIndex: stmts.length });
|
|
2133
|
+
stmts.push({
|
|
2134
|
+
sql: `INSERT OR IGNORE INTO credit_lot_expirations (lot_id, user_id, amount_mc, claim_token)
|
|
2135
|
+
SELECT id, user_id, remaining_mc, ?
|
|
2136
|
+
FROM credit_lots
|
|
2137
|
+
WHERE id = ?
|
|
2138
|
+
AND remaining_mc > 0
|
|
2139
|
+
AND never_expires = 0
|
|
2140
|
+
AND expires_at <= datetime('now')`,
|
|
2141
|
+
args: [token, lotId]
|
|
2142
|
+
});
|
|
2143
|
+
stmts.push({
|
|
2144
|
+
sql: `UPDATE credit_lots
|
|
2145
|
+
SET remaining_mc = 0
|
|
2146
|
+
WHERE id = ?
|
|
2147
|
+
AND EXISTS (
|
|
2148
|
+
SELECT 1 FROM credit_lot_expirations
|
|
2149
|
+
WHERE lot_id = ? AND claim_token = ?
|
|
2150
|
+
)`,
|
|
2151
|
+
args: [lotId, lotId, token]
|
|
2152
|
+
});
|
|
2153
|
+
stmts.push({
|
|
2154
|
+
sql: `INSERT INTO ledger (user_id, amount_mc, operation, description)
|
|
2155
|
+
SELECT user_id, -amount_mc, 'credit_expired', 'credits expired'
|
|
2156
|
+
FROM credit_lot_expirations
|
|
2157
|
+
WHERE lot_id = ? AND claim_token = ?`,
|
|
2158
|
+
args: [lotId, token]
|
|
2159
|
+
});
|
|
1997
2160
|
}
|
|
1998
|
-
await db.batch(stmts, "write");
|
|
2161
|
+
const results = await db.batch(stmts, "write");
|
|
2162
|
+
const claimedTokens = claims.filter((claim) => results[claim.insertResultIndex]?.rowsAffected === 1).map((claim) => claim.token);
|
|
2163
|
+
if (claimedTokens.length === 0) return { expired_lots: 0, expired_mc: 0 };
|
|
2164
|
+
const placeholders = claimedTokens.map(() => "?").join(", ");
|
|
2165
|
+
const expired = await db.execute({
|
|
2166
|
+
sql: `SELECT user_id, amount_mc
|
|
2167
|
+
FROM credit_lot_expirations
|
|
2168
|
+
WHERE claim_token IN (${placeholders})`,
|
|
2169
|
+
args: claimedTokens
|
|
2170
|
+
});
|
|
2171
|
+
const users = new Set(expired.rows.map((row) => Number(row.user_id)));
|
|
1999
2172
|
for (const uid of users) await reconcileBalanceMc(uid);
|
|
2000
|
-
return {
|
|
2173
|
+
return {
|
|
2174
|
+
expired_lots: expired.rows.length,
|
|
2175
|
+
expired_mc: expired.rows.reduce((sum, row) => sum + Number(row.amount_mc), 0)
|
|
2176
|
+
};
|
|
2001
2177
|
}
|
|
2002
2178
|
async function migrateExistingBalancesToLots() {
|
|
2003
2179
|
const db = getDb();
|
|
@@ -2587,29 +2763,46 @@ async function ledgerExistsForStripePI(stripePI) {
|
|
|
2587
2763
|
}
|
|
2588
2764
|
async function reconcileBalanceMc(userId, knownBalanceMc) {
|
|
2589
2765
|
const db = getDb();
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2766
|
+
void knownBalanceMc;
|
|
2767
|
+
for (let attempt = 0; attempt < 8; attempt += 1) {
|
|
2768
|
+
const snapshot = await db.execute({
|
|
2769
|
+
sql: `SELECT
|
|
2770
|
+
u.balance_mc AS cached_balance_mc,
|
|
2771
|
+
COUNT(l.id) AS lot_count,
|
|
2772
|
+
COALESCE(SUM(CASE
|
|
2773
|
+
WHEN l.remaining_mc > 0
|
|
2774
|
+
AND (l.never_expires = 1 OR l.expires_at > datetime('now'))
|
|
2775
|
+
THEN l.remaining_mc ELSE 0 END), 0) AS projected_balance_mc
|
|
2776
|
+
FROM users u
|
|
2777
|
+
LEFT JOIN credit_lots l ON l.user_id = u.id
|
|
2778
|
+
WHERE u.id = ?
|
|
2779
|
+
GROUP BY u.id, u.balance_mc`,
|
|
2602
2780
|
args: [userId]
|
|
2603
2781
|
});
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2782
|
+
const row = snapshot.rows[0];
|
|
2783
|
+
if (!row) return 0;
|
|
2784
|
+
if (Number(row.lot_count ?? 0) === 0) {
|
|
2785
|
+
await ensureMigrated(Number(userId));
|
|
2786
|
+
const nowHasLots = await db.execute({
|
|
2787
|
+
sql: "SELECT 1 FROM credit_lots WHERE user_id = ? LIMIT 1",
|
|
2788
|
+
args: [userId]
|
|
2789
|
+
});
|
|
2790
|
+
if (nowHasLots.rows.length > 0) continue;
|
|
2791
|
+
}
|
|
2792
|
+
const cachedBalanceMc = Number(row.cached_balance_mc ?? 0);
|
|
2793
|
+
const projectedBalanceMc = Number(row.projected_balance_mc ?? 0);
|
|
2794
|
+
if (cachedBalanceMc === projectedBalanceMc) return projectedBalanceMc;
|
|
2795
|
+
const updated = await db.execute({
|
|
2796
|
+
sql: "UPDATE users SET balance_mc = ? WHERE id = ? AND balance_mc = ?",
|
|
2797
|
+
args: [projectedBalanceMc, userId, cachedBalanceMc]
|
|
2610
2798
|
});
|
|
2799
|
+
if (updated.rowsAffected === 1) return projectedBalanceMc;
|
|
2611
2800
|
}
|
|
2612
|
-
|
|
2801
|
+
const current = await db.execute({
|
|
2802
|
+
sql: "SELECT balance_mc FROM users WHERE id = ? LIMIT 1",
|
|
2803
|
+
args: [userId]
|
|
2804
|
+
});
|
|
2805
|
+
return Number(current.rows[0]?.balance_mc ?? 0);
|
|
2613
2806
|
}
|
|
2614
2807
|
var SiteAuditJobRowSchema = z.object({
|
|
2615
2808
|
id: z.string(),
|
|
@@ -2706,7 +2899,9 @@ export {
|
|
|
2706
2899
|
getRefresh,
|
|
2707
2900
|
revokeRefresh,
|
|
2708
2901
|
rotateRefresh,
|
|
2709
|
-
|
|
2902
|
+
claimStripeEvent,
|
|
2903
|
+
completeStripeEvent,
|
|
2904
|
+
failStripeEvent,
|
|
2710
2905
|
stripeEventAlreadyProcessed,
|
|
2711
2906
|
generateApiKey,
|
|
2712
2907
|
hashPassword,
|
|
@@ -2809,4 +3004,4 @@ export {
|
|
|
2809
3004
|
insertInboxMessage,
|
|
2810
3005
|
listActiveUserIds
|
|
2811
3006
|
};
|
|
2812
|
-
//# sourceMappingURL=chunk-
|
|
3007
|
+
//# sourceMappingURL=chunk-N7KUTTCC.js.map
|