refactor: break up large functions, add RPG/league/salary/burnout, fix bugs, add tests

- Refactor GenerateMonthlyReport (198→70), HandleCallback (128→85),
  handleHistoryCallback (131→38), handleExportCallback (100→25),
  checkAchievements (86→25) into extracted helper functions
- Add RPG system (XP, levels, streak, achievements, burnout)
- Add WorkTime League leaderboard
- Add salary estimation with configurable currency/rate
- Add input sanitization (SanitizeNote, SanitizeDisplayName)
- Add settings select-style pickers for toggles (report, RPG, league)
- Add break threshold inline picker UI
- Add event notes with pending state and /note command
- Add multi-calendar support (Jalali, Hijri)
- Add Excel export with theme picker
- Fix: getTodayBreakThreshold uses user's timezone (was UTC)
- Fix: acknowledgeCallback passes real callback ID
- Fix: currency symbol safety with currencySymbol() helper
- Fix: count work hours in summary on day-off days
- Fix: unsilence all error returns from SQL Exec/Bot API/migrations
- Remove stale db/schema.sql and unreferenced computeWeekTotals
- Extract constants: DateLayout, TimeLayout, secondsPerHour, etc.
- Add 12 new tests (XP, salary, sanitize, currency, dateutil)
- Remove duplicate package doc comment in totals.go
This commit is contained in:
2026-06-25 01:02:16 +03:30
parent 0d942c51db
commit 344c615666
18 changed files with 2510 additions and 483 deletions

View File

@@ -101,7 +101,12 @@ func checkDailyReports(ctx context.Context, h *bot.Handler, store *db.Store) {
now := time.Now().UTC()
for _, u := range users {
if !u.ReportEnabled || !u.IsActive {
if !u.IsActive {
continue
}
st, err := store.GetOrCreateSettings(u.ID)
if err != nil || !st.ReportEnabled {
continue
}
@@ -114,11 +119,11 @@ func checkDailyReports(ctx context.Context, h *bot.Handler, store *db.Store) {
today := localNow.Format("2006-01-02")
currentHHMM := localNow.Format("15:04")
if currentHHMM != u.ReportTime {
if currentHHMM != st.ReportTime {
continue
}
if u.LastReportDate != nil && *u.LastReportDate == today {
if st.LastReportDate == today {
continue
}