package models import ( "database/sql" "log" "time" ) type User struct { Id int Username string PasswordHash string IsAdmin bool } type Notification struct { ID int UserId int Subject string Body string IsRead bool CreatedAt time.Time } type Message struct { ID int SenderId int RecipientId int Subject string Message string IsRead bool CreatedAt time.Time ArchivedAt *time.Time } var db *sql.DB func SetDB(database *sql.DB) { db = database } func CreateUser(username, passwordHash string) error { _, err := db.Exec("INSERT INTO users (username, password_hash) VALUES (?, ?)", username, passwordHash) return err } func GetUserByUsername(username string) *User { row := db.QueryRow("SELECT id, username, password_hash FROM users WHERE username = ?", username) var user User err := row.Scan(&user.Id, &user.Username, &user.PasswordHash) if err != nil { if err != sql.ErrNoRows { log.Println("DB error:", err) } return nil } return &user } func GetUserByID(id int) *User { row := db.QueryRow("SELECT id, username, password_hash, is_admin FROM users WHERE id = ?", id) var user User err := row.Scan(&user.Id, &user.Username, &user.PasswordHash, &user.IsAdmin) if err != nil { if err != sql.ErrNoRows { log.Println("DB error:", err) } return nil } return &user } func LogLoginAttempt(username string, success bool) { _, err := db.Exec("INSERT INTO auditlog (username, success, timestamp) VALUES (?, ?, ?)", username, boolToInt(success), time.Now().Format(time.RFC3339)) if err != nil { log.Println("❌ Failed to log login:", err) } } func boolToInt(b bool) int { if b { return 1 } return 0 }