Skip to content

Commit 1a6ce20

Browse files
committed
fix(admin): make audit log and email log writes best-effort after subscription commit
After the subscription UPDATE succeeds, a failure in the subsequent email-log delete or audit-log insert was propagating through the outer catch and reporting success:false to the admin. This caused retry attempts to double-apply the extension (retry hits the trialing path instead of the canceled/resurrect path) and left no audit trail for the first apply. Wrap both secondary writes in their own try/catch so a failure there does not mask the already-committed subscription state change.
1 parent 07ecc8a commit 1a6ce20

1 file changed

Lines changed: 61 additions & 50 deletions

File tree

src/routers/admin/extend-claw-trial-router.ts

Lines changed: 61 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -197,21 +197,27 @@ export const extendClawTrialRouter = createTRPCRouter({
197197
continue;
198198
}
199199

200-
await createKiloClawAdminAuditLog({
201-
action: 'kiloclaw.subscription.bulk_trial_grant',
202-
actor_id: ctx.user.id,
203-
actor_email: ctx.user.google_user_email,
204-
actor_name: ctx.user.google_user_name,
205-
target_user_id: user.id,
206-
message: `Trial extended by ${trialDays} days via bulk extend, new end: ${updated.trial_ends_at}`,
207-
metadata: {
208-
source: 'bulk_extend',
209-
trialDays,
210-
previousTrialEndsAt: subscription.trial_ends_at,
211-
newTrialEndsAt: updated.trial_ends_at,
212-
action: 'extended',
213-
},
214-
});
200+
// Audit log is best-effort — its failure does not undo the extension
201+
// and must not cause a false failure result that prompts a retry.
202+
try {
203+
await createKiloClawAdminAuditLog({
204+
action: 'kiloclaw.subscription.bulk_trial_grant',
205+
actor_id: ctx.user.id,
206+
actor_email: ctx.user.google_user_email,
207+
actor_name: ctx.user.google_user_name,
208+
target_user_id: user.id,
209+
message: `Trial extended by ${trialDays} days via bulk extend, new end: ${updated.trial_ends_at}`,
210+
metadata: {
211+
source: 'bulk_extend',
212+
trialDays,
213+
previousTrialEndsAt: subscription.trial_ends_at,
214+
newTrialEndsAt: updated.trial_ends_at,
215+
action: 'extended',
216+
},
217+
});
218+
} catch {
219+
// Non-fatal
220+
}
215221

216222
results.push({
217223
email,
@@ -264,41 +270,46 @@ export const extendClawTrialRouter = createTRPCRouter({
264270
continue;
265271
}
266272

267-
// Clear billing email log entries so trial notifications can fire again
268-
// for the new trial period.
269-
const emailTypesToClear = [
270-
'claw_trial_1d',
271-
'claw_trial_5d',
272-
'claw_suspended_trial',
273-
'claw_suspended_subscription',
274-
'claw_suspended_payment',
275-
'claw_destruction_warning',
276-
'claw_instance_destroyed',
277-
];
278-
await db
279-
.delete(kiloclaw_email_log)
280-
.where(
281-
and(
282-
eq(kiloclaw_email_log.user_id, user.id),
283-
inArray(kiloclaw_email_log.email_type, emailTypesToClear)
284-
)
285-
);
286-
287-
await createKiloClawAdminAuditLog({
288-
action: 'kiloclaw.subscription.bulk_trial_grant',
289-
actor_id: ctx.user.id,
290-
actor_email: ctx.user.google_user_email,
291-
actor_name: ctx.user.google_user_name,
292-
target_user_id: user.id,
293-
message: `Trial restarted for ${trialDays} days via bulk extend (was canceled)`,
294-
metadata: {
295-
source: 'bulk_extend',
296-
trialDays,
297-
previousStatus: subscription.status,
298-
newTrialEndsAt: newEnd.toISOString(),
299-
action: 'restarted',
300-
},
301-
});
273+
// Email log clear and audit log are best-effort — their failure does
274+
// not undo the resurrection and must not cause a false failure result
275+
// that prompts a retry (which would extend rather than resurrect).
276+
try {
277+
const emailTypesToClear = [
278+
'claw_trial_1d',
279+
'claw_trial_5d',
280+
'claw_suspended_trial',
281+
'claw_suspended_subscription',
282+
'claw_suspended_payment',
283+
'claw_destruction_warning',
284+
'claw_instance_destroyed',
285+
];
286+
await db
287+
.delete(kiloclaw_email_log)
288+
.where(
289+
and(
290+
eq(kiloclaw_email_log.user_id, user.id),
291+
inArray(kiloclaw_email_log.email_type, emailTypesToClear)
292+
)
293+
);
294+
295+
await createKiloClawAdminAuditLog({
296+
action: 'kiloclaw.subscription.bulk_trial_grant',
297+
actor_id: ctx.user.id,
298+
actor_email: ctx.user.google_user_email,
299+
actor_name: ctx.user.google_user_name,
300+
target_user_id: user.id,
301+
message: `Trial restarted for ${trialDays} days via bulk extend (was canceled)`,
302+
metadata: {
303+
source: 'bulk_extend',
304+
trialDays,
305+
previousStatus: subscription.status,
306+
newTrialEndsAt: newEnd.toISOString(),
307+
action: 'restarted',
308+
},
309+
});
310+
} catch {
311+
// Non-fatal
312+
}
302313

303314
results.push({
304315
email,

0 commit comments

Comments
 (0)