refactor: split handlers.go into 5 files, redesign export month picker, pad calendar rows, improve comments

- Split 1571-line handlers.go into: handlers.go (core), clock.go, settings.go, calendar.go, report.go
- Redesigned export month picker: year navigation + 12-month grid instead of prev/next month
- Fixed calendar last row: pad remaining cells with empty buttons to ensure 7 columns
- Added Go doc comments across all files (dateutil.go, totals.go, store.go, main.go, webhook.go)
This commit is contained in:
2026-06-24 11:33:17 +03:30
parent d8599657f4
commit a8b849f8fd
11 changed files with 1366 additions and 1176 deletions

View File

@@ -87,6 +87,7 @@ func main() {
dbStore.Close()
}
// startPolling runs the long-polling update loop, dispatching messages and callbacks to the handler.
func startPolling(botAPI *tgbotapi.BotAPI, handler *bot.Handler, stop chan struct{}) {
u := tgbotapi.NewUpdate(0)
u.Timeout = 30
@@ -109,6 +110,7 @@ func startPolling(botAPI *tgbotapi.BotAPI, handler *bot.Handler, stop chan struc
}
}
// parseAllowedUsers parses a comma-separated list of Telegram user IDs into a set.
func parseAllowedUsers(raw string) map[int64]bool {
m := make(map[int64]bool)
for _, s := range strings.Split(raw, ",") {
@@ -126,6 +128,7 @@ func parseAllowedUsers(raw string) map[int64]bool {
return m
}
// dailyReportScheduler runs a periodic ticker that triggers daily report checks every 30 seconds.
func dailyReportScheduler(h *bot.Handler, store *db.Store, stop chan struct{}) {
ticker := time.NewTicker(30 * time.Second)
defer ticker.Stop()
@@ -140,6 +143,7 @@ func dailyReportScheduler(h *bot.Handler, store *db.Store, stop chan struct{}) {
}
}
// checkDailyReports iterates all users and sends a daily report to those whose report time has arrived.
func checkDailyReports(h *bot.Handler, store *db.Store) {
users, err := store.GetAllUsers()
if err != nil {
@@ -177,6 +181,7 @@ func checkDailyReports(h *bot.Handler, store *db.Store) {
}
}
// getEnvDefault returns the environment variable value or a default if unset or empty.
func getEnvDefault(key, defaultValue string) string {
if val := os.Getenv(key); val != "" {
return val

View File

@@ -10,6 +10,7 @@ import (
"worktimeBot/internal/bot"
)
// startWebhook registers the webhook with Telegram and starts the HTTPS/HTTP listener loop.
func startWebhook(botAPI *tgbotapi.BotAPI, handler *bot.Handler, webhookURL string) {
if _, err := botAPI.Request(tgbotapi.DeleteWebhookConfig{}); err != nil {
slog.Error("delete webhook", "error", err)