backend-manager 5.0.177 → 5.0.178
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/package.json
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
const { FieldValue } = require('firebase-admin/firestore');
|
|
2
|
-
|
|
3
1
|
const MAX_RETRIES = 3;
|
|
4
2
|
const RETRY_DELAY_MS = 1000;
|
|
5
3
|
|
|
6
4
|
/**
|
|
7
|
-
* onCreate - Create user doc
|
|
5
|
+
* onCreate - Create user doc
|
|
8
6
|
*
|
|
9
7
|
* This function fires for ALL user creations (including Admin SDK).
|
|
10
|
-
* It creates the user doc
|
|
8
|
+
* It creates the user doc in Firestore.
|
|
11
9
|
*
|
|
12
10
|
* Key behaviors:
|
|
13
11
|
* - Checks if user doc already exists (auth.uid) → skips if exists (handles test accounts, provider linking)
|
|
14
|
-
* - Batch writes user doc + increment count atomically
|
|
15
12
|
* - Retries up to 3 times with exponential backoff on failure
|
|
16
13
|
*
|
|
17
14
|
* If the user signed up via a provider (Google, Facebook, etc.), their display name
|
|
@@ -67,20 +64,10 @@ module.exports = async ({ Manager, assistant, user, context, libraries }) => {
|
|
|
67
64
|
|
|
68
65
|
assistant.log(`onCreate: Creating user doc for ${user.uid}`, userRecord);
|
|
69
66
|
|
|
70
|
-
//
|
|
67
|
+
// Write user doc with retry
|
|
71
68
|
try {
|
|
72
|
-
await
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
// Create user doc
|
|
76
|
-
batch.set(admin.firestore().doc(`users/${user.uid}`), userRecord);
|
|
77
|
-
|
|
78
|
-
// Increment user count (use set+merge so doc is created if missing)
|
|
79
|
-
batch.set(admin.firestore().doc('meta/stats'), {
|
|
80
|
-
users: { total: FieldValue.increment(1) },
|
|
81
|
-
}, { merge: true });
|
|
82
|
-
|
|
83
|
-
await batch.commit();
|
|
69
|
+
await retryWrite(assistant, async () => {
|
|
70
|
+
await admin.firestore().doc(`users/${user.uid}`).set(userRecord);
|
|
84
71
|
}, MAX_RETRIES, RETRY_DELAY_MS);
|
|
85
72
|
|
|
86
73
|
assistant.log(`onCreate: Successfully created user doc for ${user.uid} (${Date.now() - startTime}ms)`);
|
|
@@ -119,7 +106,7 @@ function extractProviderName(user) {
|
|
|
119
106
|
/**
|
|
120
107
|
* Retry a function up to maxRetries times with exponential backoff
|
|
121
108
|
*/
|
|
122
|
-
async function
|
|
109
|
+
async function retryWrite(assistant, fn, maxRetries, delayMs) {
|
|
123
110
|
let lastError;
|
|
124
111
|
|
|
125
112
|
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
@@ -128,7 +115,7 @@ async function retryBatchWrite(assistant, fn, maxRetries, delayMs) {
|
|
|
128
115
|
return; // Success
|
|
129
116
|
} catch (error) {
|
|
130
117
|
lastError = error;
|
|
131
|
-
assistant.error(`onCreate:
|
|
118
|
+
assistant.error(`onCreate: Write attempt ${attempt}/${maxRetries} failed:`, error);
|
|
132
119
|
|
|
133
120
|
if (attempt < maxRetries) {
|
|
134
121
|
const delay = delayMs * Math.pow(2, attempt - 1); // Exponential backoff: 1s, 2s, 4s
|
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
const { FieldValue } = require('firebase-admin/firestore');
|
|
2
|
-
|
|
3
1
|
const MAX_RETRIES = 3;
|
|
4
2
|
const RETRY_DELAY_MS = 1000;
|
|
5
3
|
|
|
6
4
|
/**
|
|
7
|
-
* onDelete - Delete user doc
|
|
5
|
+
* onDelete - Delete user doc
|
|
8
6
|
*
|
|
9
7
|
* This function fires when a user is deleted from Firebase Auth.
|
|
10
|
-
* It deletes the user doc
|
|
8
|
+
* It deletes the user doc from Firestore.
|
|
11
9
|
*
|
|
12
10
|
* Key behaviors:
|
|
13
11
|
* - Checks if user doc exists before attempting delete
|
|
14
|
-
* -
|
|
12
|
+
* - Retries up to 3 times with exponential backoff on failure
|
|
15
13
|
* - Logs timing for performance monitoring
|
|
16
14
|
*/
|
|
17
15
|
module.exports = async ({ Manager, assistant, user, context, libraries }) => {
|
|
@@ -33,20 +31,10 @@ module.exports = async ({ Manager, assistant, user, context, libraries }) => {
|
|
|
33
31
|
return;
|
|
34
32
|
}
|
|
35
33
|
|
|
36
|
-
//
|
|
34
|
+
// Delete user doc with retry
|
|
37
35
|
try {
|
|
38
|
-
await
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
// Delete user doc
|
|
42
|
-
batch.delete(admin.firestore().doc(`users/${user.uid}`));
|
|
43
|
-
|
|
44
|
-
// Decrement user count (use set+merge so doc is created if missing)
|
|
45
|
-
batch.set(admin.firestore().doc('meta/stats'), {
|
|
46
|
-
users: { total: FieldValue.increment(-1) },
|
|
47
|
-
}, { merge: true });
|
|
48
|
-
|
|
49
|
-
await batch.commit();
|
|
36
|
+
await retryWrite(assistant, async () => {
|
|
37
|
+
await admin.firestore().doc(`users/${user.uid}`).delete();
|
|
50
38
|
}, MAX_RETRIES, RETRY_DELAY_MS);
|
|
51
39
|
|
|
52
40
|
assistant.log(`onDelete: Successfully deleted user doc for ${user.uid}`);
|
|
@@ -78,7 +66,7 @@ module.exports = async ({ Manager, assistant, user, context, libraries }) => {
|
|
|
78
66
|
/**
|
|
79
67
|
* Retry a function up to maxRetries times with exponential backoff
|
|
80
68
|
*/
|
|
81
|
-
async function
|
|
69
|
+
async function retryWrite(assistant, fn, maxRetries, delayMs) {
|
|
82
70
|
let lastError;
|
|
83
71
|
|
|
84
72
|
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
@@ -87,7 +75,7 @@ async function retryBatchWrite(assistant, fn, maxRetries, delayMs) {
|
|
|
87
75
|
return; // Success
|
|
88
76
|
} catch (error) {
|
|
89
77
|
lastError = error;
|
|
90
|
-
assistant.error(`onDelete:
|
|
78
|
+
assistant.error(`onDelete: Write attempt ${attempt}/${maxRetries} failed:`, error);
|
|
91
79
|
|
|
92
80
|
if (attempt < maxRetries) {
|
|
93
81
|
const delay = delayMs * Math.pow(2, attempt - 1); // Exponential backoff: 1s, 2s, 4s
|
|
@@ -332,7 +332,7 @@ function sendCheckupEmail(assistant, uid, firstName) {
|
|
|
332
332
|
to: uid,
|
|
333
333
|
sender: 'hello',
|
|
334
334
|
categories: ['account/checkup'],
|
|
335
|
-
subject: `How
|
|
335
|
+
subject: `How is your experience with ${Manager.config.brand.name}?`,
|
|
336
336
|
template: 'default',
|
|
337
337
|
copy: false,
|
|
338
338
|
sendAt: moment().add(5, 'days').unix(),
|
|
@@ -16,7 +16,7 @@ module.exports = () => ({
|
|
|
16
16
|
sender: { types: ['string'], default: undefined },
|
|
17
17
|
subject: { types: ['string'], default: undefined },
|
|
18
18
|
template: { types: ['string'], default: undefined },
|
|
19
|
-
group: { types: ['number'], default: undefined },
|
|
19
|
+
group: { types: ['number', 'string'], default: undefined },
|
|
20
20
|
sendAt: { types: ['number', 'string'], default: undefined },
|
|
21
21
|
data: { types: ['object'], default: {} },
|
|
22
22
|
categories: { types: ['array'], default: [] },
|