fix: resolve go vet error and dayStart logic in ComputeDailyTotals

- Fix 'string(d)' int-to-rune conversion in rpg_test.go by using fmt.Sprintf
- Fix ComputeDailyTotals dayStart logic: initial state should be StateWorking
  when dayStart > 0, correctly counting work from dayStart to first out event
- Update README project structure to reflect new domain/handler/repo layout
- Implement missing achievements: rpg_pioneer (on RPG enable) and
  salary_setter (on first rate set)
- Add tryUnlockAchievement helper to Handler
This commit is contained in:
2026-06-25 09:54:22 +03:30
parent 3835b002a7
commit d15ed46066
45 changed files with 4947 additions and 5430 deletions

View File

@@ -14,8 +14,8 @@ import (
"github.com/go-telegram/bot/models"
"github.com/joho/godotenv"
"worktimeBot/internal/bot"
"worktimeBot/internal/db"
"worktimeBot/internal/handler"
"worktimeBot/internal/repo"
)
func main() {
@@ -23,12 +23,13 @@ func main() {
AddSource: true,
Level: slog.LevelInfo,
})))
godotenv.Load()
token := os.Getenv("BOT_TOKEN")
dbPath := getEnvDefault("DB_PATH", "db.sqlite3")
dbStore, err := db.NewStore(dbPath)
store, err := repo.NewStore(dbPath)
if err != nil {
slog.Error("failed to open database", "path", dbPath, "error", err)
os.Exit(1)
@@ -36,7 +37,7 @@ func main() {
allowedUsers := parseAllowedUsers(os.Getenv("BOT_ALLOWED_USERS"))
var h *bot.Handler
var h *handler.Handler
dispatch := func(ctx context.Context, b *tgbot.Bot, update *models.Update) {
if update.Message != nil {
@@ -53,7 +54,7 @@ func main() {
os.Exit(1)
}
h = bot.NewHandler(b, dbStore, allowedUsers)
h = handler.NewHandler(b, store, allowedUsers)
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer cancel()
@@ -64,7 +65,7 @@ func main() {
if _, err := b.DeleteWebhook(ctx, &tgbot.DeleteWebhookParams{}); err != nil {
slog.Warn("failed to delete webhook", "error", err)
}
go dailyReportScheduler(ctx, h, dbStore)
go dailyReportScheduler(ctx, h, store)
slog.Info("bot started",
"allowed_users", len(allowedUsers),
"mode", "polling",
@@ -72,11 +73,11 @@ func main() {
b.Start(ctx)
}
dbStore.Close()
store.Close()
}
// dailyReportScheduler runs a periodic ticker that triggers daily report checks every 30 seconds.
func dailyReportScheduler(ctx context.Context, h *bot.Handler, store *db.Store) {
func dailyReportScheduler(ctx context.Context, h *handler.Handler, store repo.Repository) {
ticker := time.NewTicker(30 * time.Second)
defer ticker.Stop()
@@ -91,7 +92,7 @@ func dailyReportScheduler(ctx context.Context, h *bot.Handler, store *db.Store)
}
// checkDailyReports iterates all users and sends a daily report to those whose report time has arrived.
func checkDailyReports(ctx context.Context, h *bot.Handler, store *db.Store) {
func checkDailyReports(ctx context.Context, h *handler.Handler, store repo.Repository) {
users, err := store.GetAllUsers()
if err != nil {
slog.Error("report scheduler: get users", "error", err)
@@ -131,6 +132,7 @@ func checkDailyReports(ctx context.Context, h *bot.Handler, store *db.Store) {
"user_id", u.ID, "chat_id", u.ChatID, "timezone", u.Timezone,
)
h.SendDailyReport(ctx, u.ID, u.ChatID)
store.MarkReportSent(u.ID, today)
}
}