chore(release): prepare v1.31.4

This commit is contained in:
Marc-André Bombeck committed 2026-07-21 01:34:29 +02:00
1 parent 3ce6726646
commit b38f41b99d
12 files changed
+99 -68

No files matched your search

+16 -16
View File
@@ -274,6 +274,22 @@ export const POST = apiHandler(async (request: NextRequest) => {
select: { id: true },
});
// Keep channel reconciliation under the same identity locks as the device
// row. Moving it after commit lets two first-time registrations race the
// compound unique key and intermittently turns one valid request into 500.
if (apnsToken) {
await tx.notificationChannel.upsert({
where: { userId_type: { userId: user.id, type: "APNS" } },
create: {
userId: user.id,
type: "APNS",
enabled: true,
config: encrypt("{}"),
},
update: {},
});
}
return { id: device.id };
});
@@ -292,22 +308,6 @@ export const POST = apiHandler(async (request: NextRequest) => {
const { id } = registration;
// Reconcile APNs channel state only after the canonical device transaction
// commits. Config is an encrypted empty record by design — the per-device
// token and environment live on the Device row.
if (apnsToken) {
await prisma.notificationChannel.upsert({
where: { userId_type: { userId: user.id, type: "APNS" } },
create: {
userId: user.id,
type: "APNS",
enabled: true,
config: encrypt("{}"),
},
update: {},
});
}
await auditLog("devices.register", {
userId: user.id,
details: {