feat: add private and profile

This commit is contained in:
2026-06-17 11:32:51 +03:30
parent 02060a4dc0
commit 0827858752
23 changed files with 972 additions and 25 deletions
+86
View File
@@ -0,0 +1,86 @@
package economy
import (
"context"
"database/sql"
)
// Stats آمار بازیِ کاربر برای نمایش در پروفایل.
type Stats struct {
Games int64 `json:"games"` // بازی کل
Wins int64 `json:"wins"` // برد کل
Losses int64 `json:"losses"` // باخت کل
KotMade int64 `json:"kot_made"` // کُت کردن
KotReceived int64 `json:"kot_received"` // کُت شدن
Cuts int64 `json:"cuts"` // بریدن (با حکم)
HakemCount int64 `json:"hakem_count"` // دست حاکم
}
// GetStats آمار کاربر را می‌خواند (اگر ردیفی نباشد، صفر برمی‌گرداند).
func (s *Service) GetStats(ctx context.Context, userID int64) (*Stats, error) {
var st Stats
err := s.db.QueryRowContext(ctx,
`SELECT games, wins, losses, kot_made, kot_received, cuts, hakem_count
FROM user_stats WHERE user_id = ?`, userID).
Scan(&st.Games, &st.Wins, &st.Losses, &st.KotMade, &st.KotReceived, &st.Cuts, &st.HakemCount)
if err == sql.ErrNoRows {
return &st, nil // هنوز بازی‌ای ثبت نشده
}
if err != nil {
return nil, err
}
return &st, nil
}
// bumpStats یک یا چند شمارنده را به‌صورت upsert افزایش می‌دهد.
// fields نگاشتِ ستون→مقدار افزوده است؛ ستون‌ها از مجموعه‌ی ثابتِ زیر می‌آیند (نه ورودی کاربر).
func (s *Service) bumpStats(ctx context.Context, userID int64, games, wins, losses, kotMade, kotRecv, cuts, hakem int64) {
_, err := s.db.ExecContext(ctx,
`INSERT INTO user_stats (user_id, games, wins, losses, kot_made, kot_received, cuts, hakem_count)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
ON CONFLICT(user_id) DO UPDATE SET
games = games + excluded.games,
wins = wins + excluded.wins,
losses = losses + excluded.losses,
kot_made = kot_made + excluded.kot_made,
kot_received = kot_received + excluded.kot_received,
cuts = cuts + excluded.cuts,
hakem_count = hakem_count + excluded.hakem_count`,
userID, games, wins, losses, kotMade, kotRecv, cuts, hakem)
if err != nil {
// آمار غیرحیاتی است؛ خطا را لاگ‌نشده می‌گذریم تا جریان بازی مختل نشود.
_ = err
}
}
// RecordHand یک هَندِ پایان‌یافته را برای کاربر ثبت می‌کند.
func (s *Service) RecordHand(ctx context.Context, userID int64, won, kot, asHakem bool) {
var kotMade, kotRecv, hakem int64
if asHakem {
hakem = 1
}
if kot {
if won {
kotMade = 1
} else {
kotRecv = 1
}
}
s.bumpStats(ctx, userID, 0, 0, 0, kotMade, kotRecv, 0, hakem)
}
// RecordCut یک بُرِش با حکم را برای کاربر ثبت می‌کند.
func (s *Service) RecordCut(ctx context.Context, userID int64) {
s.bumpStats(ctx, userID, 0, 0, 0, 0, 0, 1, 0)
}
// RecordGameResult پایانِ یک بازی را برای کاربر ثبت می‌کند (برد/باخت).
func (s *Service) RecordGameResult(ctx context.Context, userID int64, won bool) {
var wins, losses int64
if won {
wins = 1
} else {
losses = 1
}
s.bumpStats(ctx, userID, 1, wins, losses, 0, 0, 0, 0)
}