1 Commits

Author SHA1 Message Date
9758ae345d fix(subscriptions): manuel trial→active geçişte user_brands duplicate key 500'ü
Some checks failed
QA Gate (P0/P1) / Test affected app (pull_request) Has been cancelled
Full plan (brandCount=0) trial aboneliği zaten tüm markaları user_brands'te
taşıyor. activateSubscription aynı subscription için markaları tekrar insert
edince user_brands_unique_idx patlıyor — status update'i insert'ten ÖNCE
çalıştığı için abonelik yarı-aktif kalıyor ve panel 500 görüyordu
(sp.semih.ai kullanıcı detayında 'Aboneliği aktifleştir' aksiyonu).

Insert onConflictDoNothing ile idempotent yapıldı; PostHog
subscription_activated + Meta CAPI Purchase artık bu yolda da atılıyor.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 10:20:20 +03:00

View File

@@ -185,13 +185,20 @@ export class SubscriptionsService {
const allBrands = await this.db.select().from(brands).where(eq(brands.isActive, true)); const allBrands = await this.db.select().from(brands).where(eq(brands.isActive, true));
if (allBrands.length > 0) { if (allBrands.length > 0) {
await this.db.insert(userBrands).values( // Full-plan trials already carry the complete userBrands set for this
allBrands.map((b) => ({ // same subscription row; activating them must not re-insert (unique
userId: sub.userId, // (userId, subscriptionId, brandId) would abort AFTER the status
subscriptionId: sub.id, // update above, leaving a half-activated sub and a 500 to the panel).
brandId: b.id, await this.db
})), .insert(userBrands)
); .values(
allBrands.map((b) => ({
userId: sub.userId,
subscriptionId: sub.id,
brandId: b.id,
})),
)
.onConflictDoNothing();
} }
} }