diff --git a/server/internal/reward/store.go b/server/internal/reward/store.go index 605c8ea..fd81f4e 100644 --- a/server/internal/reward/store.go +++ b/server/internal/reward/store.go @@ -152,5 +152,5 @@ func isDup(err error) bool { return false } m := strings.ToLower(err.Error()) - return strings.Contains(m, "unique") || strings.Contains(m, "duplicate") || strings.Contains(m, "constraint") + return strings.Contains(m, "unique") || strings.Contains(m, "duplicate") } diff --git a/server/internal/reward/store_sqlite_test.go b/server/internal/reward/store_sqlite_test.go index 1e34e2f..b927aed 100644 --- a/server/internal/reward/store_sqlite_test.go +++ b/server/internal/reward/store_sqlite_test.go @@ -74,3 +74,25 @@ func TestInsertClaimUniqueGuards(t *testing.T) { } tx3.Rollback() } + +func TestInsertReferralUniqueInviteeGuard(t *testing.T) { + db := openDB(t) + seedU(t, db, 1, "u1") + seedU(t, db, 2, "u2") + seedU(t, db, 3, "u3") + st := NewStore(db) + now := time.Now().UTC() + + tx, _ := db.Begin() + if err := st.InsertReferralTx(context.Background(), tx, 1, 2, "dev", "reg_rewarded", &now, now); err != nil { + t.Fatal(err) + } + tx.Commit() + + // 同一 invitee(2)被另一 inviter(3)再次绑定 → invitee_id UNIQUE 命中,返回 ErrClaimExists + tx2, _ := db.Begin() + if err := st.InsertReferralTx(context.Background(), tx2, 3, 2, "dev", "reg_rewarded", &now, now); err != ErrClaimExists { + t.Fatalf("dup invitee insert err = %v, want ErrClaimExists", err) + } + tx2.Rollback() +}