@molecule/api-resource-user 1.1.0 → 1.1.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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"updatePlan.d.ts","sourceRoot":"","sources":["../../src/handlers/updatePlan.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAI7D,OAAO,KAAK,KAAK,KAAK,MAAM,aAAa,CAAA;AAMzC,oEAAoE;AACpE,MAAM,WAAW,iBAAkB,SAAQ,eAAe;IACxD,IAAI,EAAE;QACJ,OAAO,CAAC,EAAE,MAAM,CAAA;KACjB,CAAA;CACF;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,UAAU,GAAI,sCAAsC,KAAK,CAAC,QAAQ,
|
|
1
|
+
{"version":3,"file":"updatePlan.d.ts","sourceRoot":"","sources":["../../src/handlers/updatePlan.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAI7D,OAAO,KAAK,KAAK,KAAK,MAAM,aAAa,CAAA;AAMzC,oEAAoE;AACpE,MAAM,WAAW,iBAAkB,SAAQ,eAAe;IACxD,IAAI,EAAE;QACJ,OAAO,CAAC,EAAE,MAAM,CAAA;KACjB,CAAA;CACF;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,UAAU,GAAI,sCAAsC,KAAK,CAAC,QAAQ,MAiC/D,KAAK,iBAAiB;;;;;aAzBX,CAAC;;;;;;;;;;;;;;EA4Q3B,CAAA"}
|
|
@@ -25,11 +25,39 @@ export const updatePlan = ({ name, tableName, schema: _schema }) => {
|
|
|
25
25
|
tableName,
|
|
26
26
|
schema: updatePlanPropsSchema,
|
|
27
27
|
});
|
|
28
|
+
/**
|
|
29
|
+
* Fire-and-forget analytics with the failure logged (never thrown): a lost
|
|
30
|
+
* funnel event must not break a plan update, but it must not vanish either.
|
|
31
|
+
*
|
|
32
|
+
* @param name - The analytics event name.
|
|
33
|
+
* @param userId - The user the event belongs to.
|
|
34
|
+
* @param properties - Event properties.
|
|
35
|
+
*/
|
|
36
|
+
const trackSafe = (name, userId, properties) => {
|
|
37
|
+
analytics.track({ name, userId, properties }).catch((error) => {
|
|
38
|
+
logger.debug(`Analytics track failed for ${name} (best-effort)`, { userId, error });
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Log a rejected plan update before returning its 4xx. Every rejection here
|
|
43
|
+
* ends a PAID-conversion attempt, and an unlogged one leaves zero server-side
|
|
44
|
+
* trace when a user reports "the upgrade button did nothing".
|
|
45
|
+
*
|
|
46
|
+
* @param reason - Human-readable rejection reason.
|
|
47
|
+
* @param context - Request context (userId, planKey, errorKey, ...).
|
|
48
|
+
*/
|
|
49
|
+
const logRejection = (reason, context) => {
|
|
50
|
+
logger.warn(`Plan update rejected: ${reason}`, context);
|
|
51
|
+
};
|
|
28
52
|
return async (req) => {
|
|
29
53
|
try {
|
|
30
54
|
const id = req.params.id;
|
|
31
55
|
const { planKey } = req.body;
|
|
32
56
|
if (!planKey && planKey !== '') {
|
|
57
|
+
logRejection('no planKey in request body', {
|
|
58
|
+
userId: id,
|
|
59
|
+
errorKey: 'user.error.planKeyRequired',
|
|
60
|
+
});
|
|
33
61
|
return {
|
|
34
62
|
statusCode: 400,
|
|
35
63
|
body: { error: t('user.error.planKeyRequired'), errorKey: 'user.error.planKeyRequired' },
|
|
@@ -38,6 +66,7 @@ export const updatePlan = ({ name, tableName, schema: _schema }) => {
|
|
|
38
66
|
// Get the user.
|
|
39
67
|
const user = await findById(tableName, id);
|
|
40
68
|
if (!user) {
|
|
69
|
+
logRejection('user not found', { userId: id, errorKey: 'user.error.notFound' });
|
|
41
70
|
return {
|
|
42
71
|
statusCode: 404,
|
|
43
72
|
body: { error: t('user.error.notFound'), errorKey: 'user.error.notFound' },
|
|
@@ -49,6 +78,11 @@ export const updatePlan = ({ name, tableName, schema: _schema }) => {
|
|
|
49
78
|
const plan = plans.findPlan(planKey);
|
|
50
79
|
const previousPlan = plans.findPlan(user.planKey || '');
|
|
51
80
|
if (!plan) {
|
|
81
|
+
logRejection('planKey not in the plan catalogue', {
|
|
82
|
+
userId: id,
|
|
83
|
+
planKey,
|
|
84
|
+
errorKey: 'user.error.invalidPlan',
|
|
85
|
+
});
|
|
52
86
|
return {
|
|
53
87
|
statusCode: 400,
|
|
54
88
|
body: { error: t('user.error.invalidPlan'), errorKey: 'user.error.invalidPlan' },
|
|
@@ -74,32 +108,20 @@ export const updatePlan = ({ name, tableName, schema: _schema }) => {
|
|
|
74
108
|
});
|
|
75
109
|
if (result.checkoutUrl) {
|
|
76
110
|
// New subscription requires checkout — return the URL to the client.
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
previousPlanKey: previousPlan?.planKey,
|
|
83
|
-
newPlanKey: plan.planKey,
|
|
84
|
-
platformKey: plan.platformKey,
|
|
85
|
-
},
|
|
86
|
-
})
|
|
87
|
-
.catch(() => { });
|
|
111
|
+
trackSafe('user.plan_checkout_created', id, {
|
|
112
|
+
previousPlanKey: previousPlan?.planKey,
|
|
113
|
+
newPlanKey: plan.planKey,
|
|
114
|
+
platformKey: plan.platformKey,
|
|
115
|
+
});
|
|
88
116
|
return { statusCode: 201, body: { checkoutUrl: result.checkoutUrl } };
|
|
89
117
|
}
|
|
90
118
|
if (result.updated) {
|
|
91
119
|
// Subscription was updated in-place — update the user record.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
previousPlanKey: previousPlan?.planKey,
|
|
98
|
-
newPlanKey: plan.planKey,
|
|
99
|
-
platformKey: plan.platformKey,
|
|
100
|
-
},
|
|
101
|
-
})
|
|
102
|
-
.catch(() => { });
|
|
120
|
+
trackSafe('user.plan_updated', id, {
|
|
121
|
+
previousPlanKey: previousPlan?.planKey,
|
|
122
|
+
newPlanKey: plan.planKey,
|
|
123
|
+
platformKey: plan.platformKey,
|
|
124
|
+
});
|
|
103
125
|
const updated = await updateResource({
|
|
104
126
|
id,
|
|
105
127
|
props: {
|
|
@@ -113,17 +135,20 @@ export const updatePlan = ({ name, tableName, schema: _schema }) => {
|
|
|
113
135
|
invalidateEntitlementsCacheSafe(id);
|
|
114
136
|
return updated;
|
|
115
137
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
138
|
+
trackSafe('user.plan_update_failed', id, {
|
|
139
|
+
previousPlanKey: previousPlan?.planKey,
|
|
140
|
+
newPlanKey: plan.planKey,
|
|
141
|
+
platformKey: plan.platformKey,
|
|
142
|
+
});
|
|
143
|
+
// The provider swallowed its own error into { updated: false } (a
|
|
144
|
+
// declined card, an unknown price id, a misconfigured product) —
|
|
145
|
+
// this line is the only request-scoped trace of a LOST conversion.
|
|
146
|
+
logRejection('payment provider did not update the subscription', {
|
|
119
147
|
userId: id,
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
},
|
|
125
|
-
})
|
|
126
|
-
.catch(() => { });
|
|
148
|
+
planKey,
|
|
149
|
+
platformKey: plan.platformKey,
|
|
150
|
+
errorKey: 'user.error.failedToUpdateSubscription',
|
|
151
|
+
});
|
|
127
152
|
return {
|
|
128
153
|
statusCode: 400,
|
|
129
154
|
body: {
|
|
@@ -139,6 +164,12 @@ export const updatePlan = ({ name, tableName, schema: _schema }) => {
|
|
|
139
164
|
// verification (POST /users/:id/verify-payment/:provider). Falling
|
|
140
165
|
// through here previously let a user self-grant a paid (Pro) plan with
|
|
141
166
|
// no payment.
|
|
167
|
+
logRejection('provider has no updateSubscription — verification required', {
|
|
168
|
+
userId: id,
|
|
169
|
+
planKey,
|
|
170
|
+
platformKey: plan.platformKey,
|
|
171
|
+
errorKey: 'user.error.subscriptionActivationRequiresVerification',
|
|
172
|
+
});
|
|
142
173
|
return {
|
|
143
174
|
statusCode: 400,
|
|
144
175
|
body: {
|
|
@@ -154,13 +185,10 @@ export const updatePlan = ({ name, tableName, schema: _schema }) => {
|
|
|
154
185
|
// Switching to free plan. Keep current planKey if subscription hasn't expired yet.
|
|
155
186
|
const now = new Date().getTime();
|
|
156
187
|
const expires = new Date(user.planExpiresAt || 0).getTime();
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
properties: { previousPlanKey: previousPlan?.planKey, newPlanKey: '' },
|
|
162
|
-
})
|
|
163
|
-
.catch(() => { });
|
|
188
|
+
trackSafe('user.plan_updated', id, {
|
|
189
|
+
previousPlanKey: previousPlan?.planKey,
|
|
190
|
+
newPlanKey: '',
|
|
191
|
+
});
|
|
164
192
|
const downgraded = await updateResource({
|
|
165
193
|
id,
|
|
166
194
|
props: {
|
|
@@ -180,6 +208,11 @@ export const updatePlan = ({ name, tableName, schema: _schema }) => {
|
|
|
180
208
|
// (checkout/in-place) or receipt verification
|
|
181
209
|
// (POST /users/:id/verify-payment/:provider). This closes the
|
|
182
210
|
// self-grant escalation where a user PATCHed a paid planKey directly.
|
|
211
|
+
logRejection('paid plan has no payment platform handler', {
|
|
212
|
+
userId: id,
|
|
213
|
+
planKey,
|
|
214
|
+
errorKey: 'user.error.subscriptionActivationRequiresVerification',
|
|
215
|
+
});
|
|
183
216
|
return {
|
|
184
217
|
statusCode: 400,
|
|
185
218
|
body: {
|
|
@@ -194,6 +227,11 @@ export const updatePlan = ({ name, tableName, schema: _schema }) => {
|
|
|
194
227
|
// Upgrades MUST go through a bonded PlanService + PaymentProvider to prevent
|
|
195
228
|
// privilege escalation (users setting planKey to a paid tier without payment).
|
|
196
229
|
if (planKey !== '') {
|
|
230
|
+
logRejection('no plans service bonded — paid planKey refused', {
|
|
231
|
+
userId: id,
|
|
232
|
+
planKey,
|
|
233
|
+
errorKey: 'user.error.failedToUpdatePlan',
|
|
234
|
+
});
|
|
197
235
|
return {
|
|
198
236
|
statusCode: 400,
|
|
199
237
|
body: {
|
|
@@ -202,13 +240,7 @@ export const updatePlan = ({ name, tableName, schema: _schema }) => {
|
|
|
202
240
|
},
|
|
203
241
|
};
|
|
204
242
|
}
|
|
205
|
-
|
|
206
|
-
.track({
|
|
207
|
-
name: 'user.plan_updated',
|
|
208
|
-
userId: id,
|
|
209
|
-
properties: { newPlanKey: planKey },
|
|
210
|
-
})
|
|
211
|
-
.catch(() => { });
|
|
243
|
+
trackSafe('user.plan_updated', id, { newPlanKey: planKey });
|
|
212
244
|
const result = await updateResource({ id, props: { planKey, planAutoRenews: false } });
|
|
213
245
|
// Drop the cached plan key so the downgrade takes effect immediately,
|
|
214
246
|
// not after the entitlements cache TTL.
|
|
@@ -228,7 +260,11 @@ export const updatePlan = ({ name, tableName, schema: _schema }) => {
|
|
|
228
260
|
body: { error: error.message, errorKey: error.errorKey },
|
|
229
261
|
};
|
|
230
262
|
}
|
|
231
|
-
logger.error(
|
|
263
|
+
logger.error('Plan update failed', {
|
|
264
|
+
userId: req.params.id,
|
|
265
|
+
planKey: req.body?.planKey,
|
|
266
|
+
error,
|
|
267
|
+
});
|
|
232
268
|
return {
|
|
233
269
|
statusCode: 500,
|
|
234
270
|
body: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"updatePlan.js","sourceRoot":"","sources":["../../src/handlers/updatePlan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AACjE,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AACjD,OAAO,EAAE,CAAC,EAAE,MAAM,oBAAoB,CAAA;AACtC,OAAO,EACL,0BAA0B,GAG3B,MAAM,wBAAwB,CAAA;AAE/B,OAAO,EAAE,MAAM,IAAI,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAEjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AAEpD,OAAO,EAAE,+BAA+B,EAAE,MAAM,wCAAwC,CAAA;AAExF,MAAM,SAAS,GAAG,YAAY,EAAE,CAAA;AAChC,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;AAS1B;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAkB,EAAE,EAAE;IACjF,MAAM,cAAc,GAAG,cAAc,CAAC;QACpC,IAAI;QACJ,SAAS;QACT,MAAM,EAAE,qBAAqB;KAC9B,CAAC,CAAA;IAEF,OAAO,KAAK,EAAE,GAAsB,EAAE,EAAE;QACtC,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,EAAY,CAAA;YAClC,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC,IAAI,CAAA;YAE5B,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,EAAE,EAAE,CAAC;gBAC/B,OAAO;oBACL,UAAU,EAAE,GAAG;oBACf,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,4BAA4B,CAAC,EAAE,QAAQ,EAAE,4BAA4B,EAAE;iBACzF,CAAA;YACH,CAAC;YAED,gBAAgB;YAChB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAc,SAAS,EAAE,EAAE,CAAC,CAAA;YAEvD,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO;oBACL,UAAU,EAAE,GAAG;oBACf,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,qBAAqB,CAAC,EAAE,QAAQ,EAAE,qBAAqB,EAAE;iBAC3E,CAAA;YACH,CAAC;YAED,8BAA8B;YAC9B,MAAM,KAAK,GAAG,GAAG,CAAc,OAAO,CAAC,CAAA;YAEvC,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;gBACpC,MAAM,YAAY,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAA;gBAEvD,IAAI,CAAC,IAAI,EAAE,CAAC;oBACV,OAAO;wBACL,UAAU,EAAE,GAAG;wBACf,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,wBAAwB,CAAC,EAAE,QAAQ,EAAE,wBAAwB,EAAE;qBACjF,CAAA;gBACH,CAAC;gBAED,iFAAiF;gBACjF,IACE,YAAY;oBACZ,YAAY,CAAC,WAAW;oBACxB,YAAY,CAAC,WAAW,KAAK,IAAI,CAAC,WAAW,EAC7C,CAAC;oBACD,MAAM,gBAAgB,GAAG,GAAG,CAAkB,UAAU,EAAE,YAAY,CAAC,WAAW,CAAC,CAAA;oBACnF,IAAI,gBAAgB,EAAE,kBAAkB,EAAE,CAAC;wBACzC,MAAM,gBAAgB,CAAC,kBAAkB,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAA;oBAChE,CAAC;gBACH,CAAC;gBAED,+DAA+D;gBAC/D,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;oBACrB,MAAM,eAAe,GAAG,GAAG,CAAkB,UAAU,EAAE,IAAI,CAAC,WAAW,CAAC,CAAA;oBAC1E,IAAI,eAAe,EAAE,kBAAkB,EAAE,CAAC;wBACxC,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,kBAAkB,CAAC;4BACtD,MAAM,EAAE,IAAI,CAAC,EAAE;4BACf,YAAY,EAAE,IAAI,CAAC,iBAAiB;4BACpC,iBAAiB,EAAE,YAAY,EAAE,iBAAiB;yBACnD,CAAC,CAAA;wBAEF,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;4BACvB,qEAAqE;4BACrE,SAAS
|
|
1
|
+
{"version":3,"file":"updatePlan.js","sourceRoot":"","sources":["../../src/handlers/updatePlan.ts"],"names":[],"mappings":"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"}
|