From 32446a99d175a2dcd07742e47400f884a33dd2f8 Mon Sep 17 00:00:00 2001 From: db123 Date: Tue, 23 Jun 2026 22:00:25 +0330 Subject: [PATCH] =?UTF-8?q?Fix=20break=20tracking=20(out=E2=86=92in=20gap)?= =?UTF-8?q?,=20add=20startup=20log,=20clean=20up=20/start=20message?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/bot/main.go | 2 ++ internal/bot/handlers.go | 2 +- internal/bot/totals.go | 31 ++++++++++++------------------- 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/cmd/bot/main.go b/cmd/bot/main.go index eb89197..66171cb 100644 --- a/cmd/bot/main.go +++ b/cmd/bot/main.go @@ -37,6 +37,8 @@ func main() { handler := bot.NewHandler(botAPI, dbStore, allowedUsers) + log.Printf("Bot started. Allowed users: %d", len(allowedUsers)) + webhookURL := os.Getenv("BOT_WEBHOOK_URL") if webhookURL != "" { startWebhook(botAPI, handler, webhookURL) diff --git a/internal/bot/handlers.go b/internal/bot/handlers.go index aa47998..4efc24a 100644 --- a/internal/bot/handlers.go +++ b/internal/bot/handlers.go @@ -82,7 +82,7 @@ func (h *Handler) handleStart(msg *tgbotapi.Message) { h.Bot.Send(reply) kb := quickKeyboard() - quick := tgbotapi.NewMessage(msg.Chat.ID, "Use the buttons below to quickly clock in/out:") + quick := tgbotapi.NewMessage(msg.Chat.ID, "—") quick.ReplyMarkup = kb h.Bot.Send(quick) } diff --git a/internal/bot/totals.go b/internal/bot/totals.go index 2ea575c..3ce1d67 100644 --- a/internal/bot/totals.go +++ b/internal/bot/totals.go @@ -14,16 +14,12 @@ const ( StateOnBreak ) -// DailyTotals holds aggregated times for a single day. type DailyTotals struct { TotalSeconds int64 BreakSeconds int64 PairCount int } -// ComputeDailyTotals pairs events with break inference. -// Multi‑out sequences: first out ends work, second out starts break, -// next in ends break, next out ends work, etc. func ComputeDailyTotals(events []db.Event) DailyTotals { if len(events) == 0 { return DailyTotals{} @@ -40,34 +36,31 @@ func ComputeDailyTotals(events []db.Event) DailyTotals { state := StateIdle for _, e := range sorted { - switch { - case e.EventType == "in": + switch e.EventType { + case "in": switch state { - case StateIdle, StateOnBreak: - if state == StateOnBreak { - breakTotal += e.OccurredAt - breakStart - breakStart = 0 - } + case StateIdle: + workStart = e.OccurredAt + state = StateWorking + case StateOnBreak: + breakTotal += e.OccurredAt - breakStart + breakStart = 0 workStart = e.OccurredAt state = StateWorking - // Working → ignore duplicate in (shouldn't happen) - case StateWorking: - // already working, ignore } - case e.EventType == "out": + case "out": switch state { case StateWorking: - // End of work period workTotal += e.OccurredAt - workStart workStart = 0 pairs++ - state = StateIdle + breakStart = e.OccurredAt + state = StateOnBreak case StateIdle: - // Second consecutive out → break start breakStart = e.OccurredAt state = StateOnBreak case StateOnBreak: - // Duplicate break start – ignore + breakStart = e.OccurredAt } } }