Skip to content

Commit ad39b11

Browse files
jchrisclaude
andcommitted
fix: handle duplicate ledger user gracefully with onConflictDoNothing
When a user is already in a ledger, the insert now returns the existing record instead of failing with a constraint violation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent ae60716 commit ad39b11

File tree

1 file changed

+39
-16
lines changed

1 file changed

+39
-16
lines changed

dashboard/backend/internal/add-user-to-ledger.ts

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -63,23 +63,46 @@ export async function addUserToLedger(ctx: FPApiSQLCtx, req: AddUserToLedger): P
6363
.where(and(eq(sqlLedgerUsers.userId, req.userId), ne(sqlLedgerUsers.default, 0)))
6464
.run();
6565
}
66-
const ret = (
67-
await ctx.db
68-
.insert(sqlLedgerUsers)
69-
.values({
70-
ledgerId: ledger.Ledgers.ledgerId,
71-
userId: req.userId,
72-
name: req.userName,
73-
role: req.role,
74-
right: req.right,
75-
default: req.default ? 1 : 0,
76-
createdAt: now,
77-
updatedAt: now,
78-
})
79-
.returning()
80-
)[0];
66+
const inserted = await ctx.db
67+
.insert(sqlLedgerUsers)
68+
.values({
69+
ledgerId: ledger.Ledgers.ledgerId,
70+
userId: req.userId,
71+
name: req.userName,
72+
role: req.role,
73+
right: req.right,
74+
default: req.default ? 1 : 0,
75+
createdAt: now,
76+
updatedAt: now,
77+
})
78+
.onConflictDoNothing()
79+
.returning();
80+
if (inserted.length === 0) {
81+
// User already exists in ledger, fetch existing record
82+
const existing = await ctx.db
83+
.select()
84+
.from(sqlLedgerUsers)
85+
.where(and(eq(sqlLedgerUsers.ledgerId, ledger.Ledgers.ledgerId), eq(sqlLedgerUsers.userId, req.userId)))
86+
.get();
87+
if (!existing) {
88+
return Result.Err("failed to insert or find ledger user");
89+
}
90+
return Result.Ok({
91+
ledgerName: toUndef(ledger.Ledgers.name),
92+
userName: toUndef(existing.name),
93+
ledgerId: ledger.Ledgers.ledgerId,
94+
tenantId: ledger.Ledgers.tenantId,
95+
status: existing.status as UserStatus,
96+
statusReason: existing.statusReason,
97+
userId: req.userId,
98+
default: !!existing.default,
99+
role: toRole(existing.role),
100+
right: toReadWrite(existing.right),
101+
});
102+
}
103+
const ret = inserted[0];
81104
return Result.Ok({
82-
ledgerName: ledger.Ledgers.name,
105+
ledgerName: toUndef(ledger.Ledgers.name),
83106
userName: req.userName,
84107
ledgerId: ledger.Ledgers.ledgerId,
85108
tenantId: ledger.Ledgers.tenantId,

0 commit comments

Comments
 (0)