From ce9bf684bd8c8d7728b6041f1e10bb44514a0ba3 Mon Sep 17 00:00:00 2001 From: Johnny Luo Date: Sun, 5 Apr 2026 09:26:15 +1000 Subject: [PATCH 1/4] fix: expand token column size and fix composite index exceeding MySQL limit - Increase Token from varchar(255) to varchar(512) to accommodate longer push tokens - Remove Token from idx_vault_party unique index; composite (vault_id, party_name, token) with utf8mb4 exceeded MySQL's 3072-byte InnoDB index limit - Unique constraint is now (vault_id, party_name) with a separate regular index on token - Update RegisterDevice upsert to conflict on (vault_id, party_name) and update token on re-registration Co-Authored-By: Claude Sonnet 4.6 --- models/device.go | 2 +- storage/database.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/models/device.go b/models/device.go index 001539c..6b0a873 100644 --- a/models/device.go +++ b/models/device.go @@ -9,7 +9,7 @@ import ( type Device struct { VaultId string `gorm:"type:varchar(255);not null;uniqueIndex:idx_vault_party" json:"vault_id" binding:"required"` PartyName string `gorm:"type:varchar(255);not null;uniqueIndex:idx_vault_party" json:"party_name" binding:"required"` - Token string `gorm:"type:varchar(255);not null;uniqueIndex:idx_vault_party" json:"token" binding:"required"` + Token string `gorm:"type:varchar(512);not null;index:idx_token" json:"token" binding:"required"` DeviceType string `gorm:"type:varchar(255);not null" json:"device_type" binding:"required"` // apple, android, or web } diff --git a/storage/database.go b/storage/database.go index 6ff490d..f504dfb 100644 --- a/storage/database.go +++ b/storage/database.go @@ -49,8 +49,8 @@ func (d *Database) RegisterDevice(ctx context.Context, device models.Device) err deviceModel := device.GetDeviceDBModel() result := d.db.WithContext(newContext). Clauses(clause.OnConflict{ - Columns: []clause.Column{{Name: "vault_id"}, {Name: "party_name"}, {Name: "token"}}, - DoUpdates: clause.AssignmentColumns([]string{"device_type", "updated_at"}), + Columns: []clause.Column{{Name: "vault_id"}, {Name: "party_name"}}, + DoUpdates: clause.AssignmentColumns([]string{"token", "device_type", "updated_at"}), }). Create(&deviceModel) if result.Error != nil { From d333db41a0d87210306e56c2603ef79a88584d6a Mon Sep 17 00:00:00 2001 From: Johnny Luo Date: Sun, 5 Apr 2026 09:32:33 +1000 Subject: [PATCH 2/4] fix: reduce VaultId column size to varchar(64) Co-Authored-By: Claude Sonnet 4.6 --- models/device.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/device.go b/models/device.go index 6b0a873..5177c0d 100644 --- a/models/device.go +++ b/models/device.go @@ -7,7 +7,7 @@ import ( ) type Device struct { - VaultId string `gorm:"type:varchar(255);not null;uniqueIndex:idx_vault_party" json:"vault_id" binding:"required"` + VaultId string `gorm:"type:varchar(64);not null;uniqueIndex:idx_vault_party" json:"vault_id" binding:"required"` PartyName string `gorm:"type:varchar(255);not null;uniqueIndex:idx_vault_party" json:"party_name" binding:"required"` Token string `gorm:"type:varchar(512);not null;index:idx_token" json:"token" binding:"required"` DeviceType string `gorm:"type:varchar(255);not null" json:"device_type" binding:"required"` // apple, android, or web From f2ac4b9ca02e6b99e0230b47185dab8100b05179 Mon Sep 17 00:00:00 2001 From: Johnny Luo Date: Sun, 5 Apr 2026 09:34:32 +1000 Subject: [PATCH 3/4] revert: restore original OnConflict logic in RegisterDevice Co-Authored-By: Claude Sonnet 4.6 --- storage/database.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/database.go b/storage/database.go index f504dfb..6ff490d 100644 --- a/storage/database.go +++ b/storage/database.go @@ -49,8 +49,8 @@ func (d *Database) RegisterDevice(ctx context.Context, device models.Device) err deviceModel := device.GetDeviceDBModel() result := d.db.WithContext(newContext). Clauses(clause.OnConflict{ - Columns: []clause.Column{{Name: "vault_id"}, {Name: "party_name"}}, - DoUpdates: clause.AssignmentColumns([]string{"token", "device_type", "updated_at"}), + Columns: []clause.Column{{Name: "vault_id"}, {Name: "party_name"}, {Name: "token"}}, + DoUpdates: clause.AssignmentColumns([]string{"device_type", "updated_at"}), }). Create(&deviceModel) if result.Error != nil { From 8c38e10cf4b9ee1864fdb0f898beb96ffa54e3a0 Mon Sep 17 00:00:00 2001 From: Johnny Luo Date: Sun, 5 Apr 2026 09:36:23 +1000 Subject: [PATCH 4/4] fix: tighten column sizes and restore token in composite index - PartyName: varchar(255) -> varchar(128) - Token: restored to uniqueIndex:idx_vault_party (removed separate idx_token) - DeviceType: varchar(255) -> varchar(64) - Combined index (64+128+512)*4 = 2816 bytes, within MySQL's 3072-byte limit Co-Authored-By: Claude Sonnet 4.6 --- models/device.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/models/device.go b/models/device.go index 5177c0d..fa48bab 100644 --- a/models/device.go +++ b/models/device.go @@ -8,9 +8,9 @@ import ( type Device struct { VaultId string `gorm:"type:varchar(64);not null;uniqueIndex:idx_vault_party" json:"vault_id" binding:"required"` - PartyName string `gorm:"type:varchar(255);not null;uniqueIndex:idx_vault_party" json:"party_name" binding:"required"` - Token string `gorm:"type:varchar(512);not null;index:idx_token" json:"token" binding:"required"` - DeviceType string `gorm:"type:varchar(255);not null" json:"device_type" binding:"required"` // apple, android, or web + PartyName string `gorm:"type:varchar(128);not null;uniqueIndex:idx_vault_party" json:"party_name" binding:"required"` + Token string `gorm:"type:varchar(512);not null;uniqueIndex:idx_vault_party" json:"token" binding:"required"` + DeviceType string `gorm:"type:varchar(64);not null" json:"device_type" binding:"required"` // apple, android, or web } type DeviceDBModel struct {