Parça Uzmanları sıralaması artık aylık sezon: liderlik tablosu içinde
bulunulan TR-ayının (Europe/Istanbul) puanlarını gösterir ve her ayın
1'i 00:00 TR'de kendiliğinden sıfırlanır. expert-rewards cron'u
(BullMQ scheduler, "0 0 1 * *" tz=Europe/Istanbul) aynı anda biten
sezonu kapatır ve ilk 3 oylayıcıya üyelik uzatması verir:
1. → 30 gün, 2. → 15 gün, 3. → 7 gün (EXPERT_REWARD_LADDER).
Ödül mekaniği referral'la birebir: canlı active/trial abonelik endDate
+gün uzar, yoksa günler users.referral_credit_days'e bankalanır (sonraki
trial/aktivasyonda tüketilir). oem_expert_rewards (migration 0017,
period+rank UNIQUE) hem denetim kaydı hem run-once garantisi — retry ya
da elle tetik çift ödül veremez. Sıralama ölçütü job ve leaderboard'da
birebir aynı (puan desc, eşitlikte puana erken ulaşan önde).
Web: uzmanlar sayfasına sezon şeridi ("Haziran 2026 sezonu" + 🥇1 ay ·
🥈15 gün · 🥉7 gün rozetleri); alt küçük-punto kural satırına aylık
sıfırlama + ödül notu eklendi. Leaderboard cevabına periodStart eklendi.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
19 lines
1.1 KiB
SQL
19 lines
1.1 KiB
SQL
-- Monthly Parça Uzmanları prizes: one row per (TR-month, rank). Written by the
|
||
-- expert-rewards cron (1st of month 00:00 Europe/Istanbul) when it closes the
|
||
-- finished season and grants the top 3 voters a subscription extension
|
||
-- (30/15/7 days). The unique index is the run-once guard — a re-run for the
|
||
-- same period inserts nothing, so days are never granted twice.
|
||
CREATE TABLE "oem_expert_rewards" (
|
||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||
"period_start" timestamp with time zone NOT NULL,
|
||
"user_id" uuid NOT NULL,
|
||
"rank" integer NOT NULL,
|
||
"points" integer NOT NULL,
|
||
"reward_days" integer NOT NULL,
|
||
"granted_at" timestamp with time zone DEFAULT now() NOT NULL
|
||
);
|
||
--> statement-breakpoint
|
||
ALTER TABLE "oem_expert_rewards" ADD CONSTRAINT "oem_expert_rewards_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||
CREATE UNIQUE INDEX "oem_expert_rewards_period_rank_idx" ON "oem_expert_rewards" USING btree ("period_start","rank");--> statement-breakpoint
|
||
CREATE INDEX "oem_expert_rewards_user_id_idx" ON "oem_expert_rewards" USING btree ("user_id");
|