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:
41
internal/bot/sanitize.go
Normal file
41
internal/bot/sanitize.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package bot
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
const maxNoteLength = 500
|
||||
const maxUsernameLength = 64
|
||||
|
||||
// SanitizeNote cleans user-provided note text: trims whitespace, limits length,
|
||||
// and removes control characters (keeps newlines).
|
||||
func SanitizeNote(s string) string {
|
||||
s = strings.TrimSpace(s)
|
||||
if len(s) > maxNoteLength {
|
||||
s = s[:maxNoteLength]
|
||||
}
|
||||
return strings.Map(func(r rune) rune {
|
||||
if r == '\n' || r == '\t' || r == ' ' {
|
||||
return r
|
||||
}
|
||||
if unicode.IsControl(r) {
|
||||
return -1
|
||||
}
|
||||
return r
|
||||
}, s)
|
||||
}
|
||||
|
||||
// SanitizeDisplayName cleans a display name (username) for safe rendering.
|
||||
func SanitizeDisplayName(s string) string {
|
||||
s = strings.TrimSpace(s)
|
||||
if len(s) > maxUsernameLength {
|
||||
s = s[:maxUsernameLength]
|
||||
}
|
||||
return strings.Map(func(r rune) rune {
|
||||
if unicode.IsControl(r) {
|
||||
return -1
|
||||
}
|
||||
return r
|
||||
}, s)
|
||||
}
|
||||
Reference in New Issue
Block a user