feat: add /setcalendar command, store tests, and improve error handling
All checks were successful
CI / build (push) Successful in 48s
All checks were successful
CI / build (push) Successful in 48s
- Add /setcalendar command for calendar type parity (Settings UI) - Add 17 store tests covering all repository methods - Add handler tests for formatDuration, fmtHHMM, fmtDDHHMM - Add domain tests for BurnoutLevel.String, NavMonth, FormatSalary - Fix silent error discarding in save* helpers (log write failures) - Fix computeAndAwardXP error handling instead of discarding - Wrap critical store.go SQL errors with fmt.Errorf context - Update README commands table with /setcalendar
This commit is contained in:
@@ -21,16 +21,16 @@ type Store struct {
|
||||
func NewStore(path string) (*Store, error) {
|
||||
db, err := sql.Open(driverName, path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("open: %w", err)
|
||||
}
|
||||
if err := db.Ping(); err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("ping: %w", err)
|
||||
}
|
||||
if _, err := db.Exec("PRAGMA journal_mode=WAL"); err != nil {
|
||||
slog.Warn("failed to set WAL mode", "error", err)
|
||||
}
|
||||
if err := runMigrations(db); err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("migrate: %w", err)
|
||||
}
|
||||
return &Store{db: db}, nil
|
||||
}
|
||||
@@ -38,33 +38,36 @@ func NewStore(path string) (*Store, error) {
|
||||
func (s *Store) DeleteUserData(userID int64) error {
|
||||
tx, err := s.db.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("delete user data begin tx: %w", err)
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
if _, err := tx.Exec(`DELETE FROM events WHERE day_id IN (SELECT id FROM days WHERE user_id=?)`, userID); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("delete user data events: %w", err)
|
||||
}
|
||||
if _, err := tx.Exec(`DELETE FROM days WHERE user_id=?`, userID); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("delete user data days: %w", err)
|
||||
}
|
||||
if _, err := tx.Exec(`DELETE FROM user_achievements WHERE user_id=?`, userID); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("delete user data achievements: %w", err)
|
||||
}
|
||||
if _, err := tx.Exec(`DELETE FROM daily_xp WHERE user_id=?`, userID); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("delete user data daily_xp: %w", err)
|
||||
}
|
||||
if _, err := tx.Exec(`DELETE FROM user_rpg WHERE user_id=?`, userID); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("delete user data rpg: %w", err)
|
||||
}
|
||||
if _, err := tx.Exec(`DELETE FROM user_settings WHERE user_id=?`, userID); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("delete user data settings: %w", err)
|
||||
}
|
||||
if _, err := tx.Exec(`DELETE FROM users WHERE id=?`, userID); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("delete user data users: %w", err)
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
if err := tx.Commit(); err != nil {
|
||||
return fmt.Errorf("delete user data commit: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Store) Close() error {
|
||||
@@ -98,7 +101,7 @@ func (s *Store) GetOrCreateUser(chatID int64) (*domain.User, error) {
|
||||
"INSERT OR IGNORE INTO users (chat_id, username) VALUES (?, ?)",
|
||||
chatID, randomUsername(),
|
||||
); err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("get or create user: %w", err)
|
||||
}
|
||||
return s.GetUserByChatID(chatID)
|
||||
}
|
||||
@@ -113,7 +116,7 @@ func (s *Store) GetUserByChatID(chatID int64) (*domain.User, error) {
|
||||
&u.ID, &u.ChatID, &u.Username, &u.Timezone, &u.IsActive,
|
||||
&u.Calendar, &u.CreatedAt, &u.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("get user by chat id: %w", err)
|
||||
}
|
||||
return &u, nil
|
||||
}
|
||||
@@ -123,7 +126,10 @@ func (s *Store) UpdateUser(user *domain.User) error {
|
||||
"UPDATE users SET username=?, timezone=?, is_active=?, calendar=?, updated_at=unixepoch() WHERE id=?",
|
||||
user.Username, user.Timezone, user.IsActive, user.Calendar, user.ID,
|
||||
)
|
||||
return err
|
||||
if err != nil {
|
||||
return fmt.Errorf("update user: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Store) GetAllUsers() ([]domain.User, error) {
|
||||
|
||||
Reference in New Issue
Block a user