ultraclaude-agent 0.0.15 → 0.0.16
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/usage-sync.d.ts.map +1 -1
- package/dist/usage-sync.js +40 -18
- package/dist/usage-sync.js.map +1 -1
- package/package.json +1 -1
- package/src/usage-sync.ts +45 -18
package/dist/usage-sync.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usage-sync.d.ts","sourceRoot":"","sources":["../src/usage-sync.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"usage-sync.d.ts","sourceRoot":"","sources":["../src/usage-sync.ts"],"names":[],"mappings":"AA6NA,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAanD;AAID,MAAM,WAAW,YAAY;IAC3B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,wBAAgB,iBAAiB,IAAI,YAAY,CA4ChD;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAavC"}
|
package/dist/usage-sync.js
CHANGED
|
@@ -3,7 +3,8 @@ import chokidar from 'chokidar';
|
|
|
3
3
|
import { readFile, readdir } from 'node:fs/promises';
|
|
4
4
|
import { homedir } from 'node:os';
|
|
5
5
|
import { join } from 'node:path';
|
|
6
|
-
import {
|
|
6
|
+
import { apiRequest } from './sync.js';
|
|
7
|
+
import { loadAllCredentials, loadCredentials, getServerUrl } from './config.js';
|
|
7
8
|
import { logger } from './logger.js';
|
|
8
9
|
// --- Paths ---
|
|
9
10
|
const ULTRA_DIR = join(homedir(), '.claude', 'ultra');
|
|
@@ -85,28 +86,49 @@ async function buildUsagePayload() {
|
|
|
85
86
|
return { accounts };
|
|
86
87
|
}
|
|
87
88
|
// --- Push to server ---
|
|
89
|
+
/**
|
|
90
|
+
* Push usage data to the server for ALL dashboard accounts.
|
|
91
|
+
* Returns true if all pushes succeeded (or there are no accounts),
|
|
92
|
+
* false if any push failed (triggering retry).
|
|
93
|
+
*/
|
|
88
94
|
async function pushUsageData(payload) {
|
|
89
95
|
const log = logger.child({ op: 'pushUsageData', accountCount: Object.keys(payload.accounts).length });
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
96
|
+
// Resolve server URL and load all dashboard credentials
|
|
97
|
+
const probeCreds = await loadCredentials();
|
|
98
|
+
if (!probeCreds) {
|
|
99
|
+
log.error('Cannot push usage — not logged in');
|
|
100
|
+
return true; // Permanent failure — don't retry
|
|
101
|
+
}
|
|
102
|
+
const serverUrl = getServerUrl(probeCreds);
|
|
103
|
+
const allCreds = await loadAllCredentials(serverUrl);
|
|
104
|
+
if (allCreds.size === 0) {
|
|
105
|
+
log.error('Cannot push usage — no accounts found');
|
|
106
|
+
return true; // Permanent failure — don't retry
|
|
98
107
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
108
|
+
log.info({ dashboardAccounts: allCreds.size }, 'Pushing usage to all dashboard accounts');
|
|
109
|
+
let anyFailed = false;
|
|
110
|
+
for (const [userId, creds] of allCreds) {
|
|
111
|
+
const result = await apiRequest('POST', '/api/sync/usage', payload, creds);
|
|
112
|
+
if (!result.success) {
|
|
113
|
+
log.warn({ userId, error: result.message }, 'Usage push failed for account — will retry');
|
|
114
|
+
anyFailed = true;
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if (!result.data.ok) {
|
|
118
|
+
const status = result.data.status;
|
|
119
|
+
if (status >= 400 && status < 500) {
|
|
120
|
+
log.error({ userId, status }, 'Usage push rejected by server for account — not retrying');
|
|
121
|
+
// 4xx for one account shouldn't block others, but don't retry this payload
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
log.warn({ userId, status }, 'Usage push failed for account — will retry');
|
|
125
|
+
anyFailed = true;
|
|
126
|
+
}
|
|
127
|
+
continue;
|
|
104
128
|
}
|
|
105
|
-
log.
|
|
106
|
-
return false;
|
|
129
|
+
log.info({ userId }, 'Usage data pushed for account');
|
|
107
130
|
}
|
|
108
|
-
|
|
109
|
-
return true;
|
|
131
|
+
return !anyFailed;
|
|
110
132
|
}
|
|
111
133
|
// --- Retry mechanism ---
|
|
112
134
|
function startRetryTimer() {
|
package/dist/usage-sync.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usage-sync.js","sourceRoot":"","sources":["../src/usage-sync.ts"],"names":[],"mappings":"AAAA,iGAAiG;AAEjG,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"usage-sync.js","sourceRoot":"","sources":["../src/usage-sync.ts"],"names":[],"mappings":"AAAA,iGAAiG;AAEjG,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChF,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,gBAAgB;AAEhB,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AACtD,MAAM,iBAAiB,GAAG,IAAI,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAC;AAC/D,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;AA8BjD,uBAAuB;AAEvB,MAAM,WAAW,GAAG,KAAK,CAAC;AAC1B,MAAM,iBAAiB,GAAG,KAAK,CAAC;AAEhC,IAAI,OAAO,GAA6C,IAAI,CAAC;AAC7D,IAAI,aAAa,GAAyC,IAAI,CAAC;AAC/D,IAAI,UAAU,GAA0C,IAAI,CAAC;AAC7D,IAAI,mBAAmB,GAA4B,IAAI,CAAC;AAExD,+BAA+B;AAE/B,KAAK,UAAU,YAAY,CAAI,QAAgB;IAC7C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACjD,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;YAAE,OAAO,IAAI,CAAC;QACjC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAM,CAAC;IAClC,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QACpB,IAAK,CAA2B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QAChE,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,gCAAgC,CAAC,CAAC;QACpE,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,KAAK,UAAU,oBAAoB;IACjC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAgC,CAAC;IAEzD,IAAI,KAAe,CAAC;IACpB,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC;IACtC,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QACpB,IAAK,CAA2B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,QAAQ,CAAC;QACpE,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,YAAY,EAAE,EAAE,mCAAmC,CAAC,CAAC;QAChF,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IAC3D,MAAM,OAAO,CAAC,GAAG,CACf,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QAC3B,MAAM,IAAI,GAAG,MAAM,YAAY,CAAuB,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC,CAAC;QAChF,IAAI,IAAI,EAAE,UAAU,EAAE,CAAC;YACrB,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QACtC,CAAC;IACH,CAAC,CAAC,CACH,CAAC;IAEF,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,wBAAwB;AAExB,KAAK,UAAU,iBAAiB;IAC9B,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,mBAAmB,EAAE,CAAC,CAAC;IAEtD,MAAM,WAAW,GAAG,MAAM,YAAY,CAAkB,iBAAiB,CAAC,CAAC;IAC3E,IAAI,CAAC,WAAW,EAAE,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7E,GAAG,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,oBAAoB,EAAE,CAAC;IAC9C,MAAM,QAAQ,GAAqC,EAAE,CAAC;IAEtD,KAAK,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtE,MAAM,WAAW,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAE5C,QAAQ,CAAC,SAAS,CAAC,GAAG;YACpB,UAAU,EAAE,SAAS;YACrB,KAAK,EAAE,WAAW,EAAE,KAAK;YACzB,QAAQ,EAAE,WAAW,EAAE,OAAO;YAC9B,iBAAiB,EAAE,WAAW,EAAE,gBAAgB;YAChD,WAAW,EAAE;gBACX,SAAS,EAAE;oBACT,eAAe,EAAE,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,eAAe;oBAC5D,SAAS,EAAE,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,SAAS;iBACjD;gBACD,SAAS,EAAE;oBACT,eAAe,EAAE,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,eAAe;oBAC5D,SAAS,EAAE,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,SAAS;iBACjD;aACF;YACD,UAAU,EAAE,KAAK,CAAC,UAAU;SAC7B,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,CAAC;AACtB,CAAC;AAED,yBAAyB;AAEzB;;;;GAIG;AACH,KAAK,UAAU,aAAa,CAAC,OAAyB;IACpD,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAEtG,wDAAwD;IACxD,MAAM,UAAU,GAAG,MAAM,eAAe,EAAE,CAAC;IAC3C,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,GAAG,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAC,CAAC,kCAAkC;IACjD,CAAC;IAED,MAAM,SAAS,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAErD,IAAI,QAAQ,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACxB,GAAG,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC,CAAC,kCAAkC;IACjD,CAAC;IAED,GAAG,CAAC,IAAI,CAAC,EAAE,iBAAiB,EAAE,QAAQ,CAAC,IAAI,EAAE,EAAE,yCAAyC,CAAC,CAAC;IAE1F,IAAI,SAAS,GAAG,KAAK,CAAC;IAEtB,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,QAAQ,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE,iBAAiB,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;QAE3E,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,EAAE,EAAE,4CAA4C,CAAC,CAAC;YAC1F,SAAS,GAAG,IAAI,CAAC;YACjB,SAAS;QACX,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;YACpB,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;YAClC,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,GAAG,GAAG,EAAE,CAAC;gBAClC,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,0DAA0D,CAAC,CAAC;gBAC1F,2EAA2E;YAC7E,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,4CAA4C,CAAC,CAAC;gBAC3E,SAAS,GAAG,IAAI,CAAC;YACnB,CAAC;YACD,SAAS;QACX,CAAC;QAED,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,+BAA+B,CAAC,CAAC;IACxD,CAAC;IAED,OAAO,CAAC,SAAS,CAAC;AACpB,CAAC;AAED,0BAA0B;AAE1B,SAAS,eAAe;IACtB,IAAI,UAAU;QAAE,OAAO;IACvB,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE;QAC5B,IAAI,CAAC,mBAAmB,EAAE,CAAC;YACzB,cAAc,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;QACD,aAAa,CAAC,mBAAmB,CAAC;aAC/B,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;YAChB,IAAI,OAAO,EAAE,CAAC;gBACZ,mBAAmB,GAAG,IAAI,CAAC;gBAC3B,cAAc,EAAE,CAAC;gBACjB,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;YACvC,CAAC;QACH,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;YACtB,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,mBAAmB,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;IACP,CAAC,EAAE,iBAAiB,CAAC,CAAC;AACxB,CAAC;AAED,SAAS,cAAc;IACrB,IAAI,UAAU,EAAE,CAAC;QACf,aAAa,CAAC,UAAU,CAAC,CAAC;QAC1B,UAAU,GAAG,IAAI,CAAC;IACpB,CAAC;AACH,CAAC;AAED,6BAA6B;AAE7B,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,OAAO,GAAG,MAAM,iBAAiB,EAAE,CAAC;IAC1C,IAAI,CAAC,OAAO;QAAE,OAAO;IAErB,0CAA0C;IAC1C,mBAAmB,GAAG,IAAI,CAAC;IAC3B,cAAc,EAAE,CAAC;IAEjB,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,OAAO,CAAC,CAAC;IAC7C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,mBAAmB,GAAG,OAAO,CAAC;QAC9B,eAAe,EAAE,CAAC;IACpB,CAAC;AACH,CAAC;AAQD,MAAM,UAAU,iBAAiB;IAC/B,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,cAAc,EAAE,CAAC,CAAC;IAEjD,SAAS,iBAAiB;QACxB,IAAI,aAAa;YAAE,YAAY,CAAC,aAAa,CAAC,CAAC;QAC/C,aAAa,GAAG,UAAU,CAAC,GAAG,EAAE;YAC9B,aAAa,GAAG,IAAI,CAAC;YACrB,aAAa,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;gBACrC,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,mBAAmB,CAAC,CAAC;YAC1C,CAAC,CAAC,CAAC;QACL,CAAC,EAAE,WAAW,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,iBAAiB,EAAE,YAAY,CAAC,EAAE;QAC1D,UAAU,EAAE,IAAI;QAChB,aAAa,EAAE,IAAI;QACnB,gBAAgB,EAAE;YAChB,kBAAkB,EAAE,GAAG;YACvB,YAAY,EAAE,GAAG;SAClB;KACF,CAAC,CAAC;IAEH,OAAO;SACJ,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC;SAC5B,EAAE,CAAC,QAAQ,EAAE,iBAAiB,CAAC;SAC/B,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAEnE,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,iBAAiB,EAAE,YAAY,CAAC,EAAE,EAAE,uBAAuB,CAAC,CAAC;IAEhF,OAAO;QACL,KAAK,CAAC,KAAK;YACT,IAAI,aAAa,EAAE,CAAC;gBAClB,YAAY,CAAC,aAAa,CAAC,CAAC;gBAC5B,aAAa,GAAG,IAAI,CAAC;YACvB,CAAC;YACD,cAAc,EAAE,CAAC;YACjB,mBAAmB,GAAG,IAAI,CAAC;YAC3B,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;gBACtB,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;YACD,GAAG,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QACpC,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,IAAI,aAAa,EAAE,CAAC;QAClB,YAAY,CAAC,aAAa,CAAC,CAAC;QAC5B,aAAa,GAAG,IAAI,CAAC;IACvB,CAAC;IACD,cAAc,EAAE,CAAC;IACjB,mBAAmB,GAAG,IAAI,CAAC;IAC3B,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;YACrC,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,6BAA6B,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
package/src/usage-sync.ts
CHANGED
|
@@ -5,7 +5,8 @@ import { readFile, readdir } from 'node:fs/promises';
|
|
|
5
5
|
import { homedir } from 'node:os';
|
|
6
6
|
import { join } from 'node:path';
|
|
7
7
|
import type { SyncUsageAccount, SyncUsageRequest } from '@ultra-claude/shared';
|
|
8
|
-
import {
|
|
8
|
+
import { apiRequest } from './sync.js';
|
|
9
|
+
import { loadAllCredentials, loadCredentials, getServerUrl } from './config.js';
|
|
9
10
|
import { logger } from './logger.js';
|
|
10
11
|
|
|
11
12
|
// --- Paths ---
|
|
@@ -132,32 +133,58 @@ async function buildUsagePayload(): Promise<SyncUsageRequest | null> {
|
|
|
132
133
|
|
|
133
134
|
// --- Push to server ---
|
|
134
135
|
|
|
136
|
+
/**
|
|
137
|
+
* Push usage data to the server for ALL dashboard accounts.
|
|
138
|
+
* Returns true if all pushes succeeded (or there are no accounts),
|
|
139
|
+
* false if any push failed (triggering retry).
|
|
140
|
+
*/
|
|
135
141
|
async function pushUsageData(payload: SyncUsageRequest): Promise<boolean> {
|
|
136
142
|
const log = logger.child({ op: 'pushUsageData', accountCount: Object.keys(payload.accounts).length });
|
|
137
143
|
|
|
138
|
-
|
|
144
|
+
// Resolve server URL and load all dashboard credentials
|
|
145
|
+
const probeCreds = await loadCredentials();
|
|
146
|
+
if (!probeCreds) {
|
|
147
|
+
log.error('Cannot push usage — not logged in');
|
|
148
|
+
return true; // Permanent failure — don't retry
|
|
149
|
+
}
|
|
139
150
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
return false;
|
|
151
|
+
const serverUrl = getServerUrl(probeCreds);
|
|
152
|
+
const allCreds = await loadAllCredentials(serverUrl);
|
|
153
|
+
|
|
154
|
+
if (allCreds.size === 0) {
|
|
155
|
+
log.error('Cannot push usage — no accounts found');
|
|
156
|
+
return true; // Permanent failure — don't retry
|
|
147
157
|
}
|
|
148
158
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
159
|
+
log.info({ dashboardAccounts: allCreds.size }, 'Pushing usage to all dashboard accounts');
|
|
160
|
+
|
|
161
|
+
let anyFailed = false;
|
|
162
|
+
|
|
163
|
+
for (const [userId, creds] of allCreds) {
|
|
164
|
+
const result = await apiRequest('POST', '/api/sync/usage', payload, creds);
|
|
165
|
+
|
|
166
|
+
if (!result.success) {
|
|
167
|
+
log.warn({ userId, error: result.message }, 'Usage push failed for account — will retry');
|
|
168
|
+
anyFailed = true;
|
|
169
|
+
continue;
|
|
154
170
|
}
|
|
155
|
-
|
|
156
|
-
|
|
171
|
+
|
|
172
|
+
if (!result.data.ok) {
|
|
173
|
+
const status = result.data.status;
|
|
174
|
+
if (status >= 400 && status < 500) {
|
|
175
|
+
log.error({ userId, status }, 'Usage push rejected by server for account — not retrying');
|
|
176
|
+
// 4xx for one account shouldn't block others, but don't retry this payload
|
|
177
|
+
} else {
|
|
178
|
+
log.warn({ userId, status }, 'Usage push failed for account — will retry');
|
|
179
|
+
anyFailed = true;
|
|
180
|
+
}
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
log.info({ userId }, 'Usage data pushed for account');
|
|
157
185
|
}
|
|
158
186
|
|
|
159
|
-
|
|
160
|
-
return true;
|
|
187
|
+
return !anyFailed;
|
|
161
188
|
}
|
|
162
189
|
|
|
163
190
|
// --- Retry mechanism ---
|