package models import ( "context" "time" ) // User represents a registered user account. type User struct { Base ID string `json:"id"` Nick string `json:"nick"` PasswordHash string `json:"-"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` LastSeenAt *time.Time `json:"lastSeenAt,omitempty"` } // Channels returns all channels the user is a member of. func (u *User) Channels(ctx context.Context) ([]*Channel, error) { rows, err := u.GetDB().QueryContext(ctx, ` SELECT c.id, c.name, c.topic, c.modes, c.created_at, c.updated_at FROM channels c JOIN channel_members cm ON cm.channel_id = c.id WHERE cm.user_id = ? ORDER BY c.name`, u.ID, ) if err != nil { return nil, err } defer func() { _ = rows.Close() }() channels := []*Channel{} for rows.Next() { c := &Channel{} c.SetDB(u.db) err = rows.Scan( &c.ID, &c.Name, &c.Topic, &c.Modes, &c.CreatedAt, &c.UpdatedAt, ) if err != nil { return nil, err } channels = append(channels, c) } return channels, rows.Err() } // QueuedMessages returns undelivered messages for this user. func (u *User) QueuedMessages(ctx context.Context) ([]*Message, error) { rows, err := u.GetDB().QueryContext(ctx, ` SELECT m.id, m.ts, m.from_user_id, m.from_nick, m.target, m.type, m.body, m.meta, m.created_at FROM messages m JOIN message_queue mq ON mq.message_id = m.id WHERE mq.user_id = ? ORDER BY mq.queued_at ASC`, u.ID, ) if err != nil { return nil, err } defer func() { _ = rows.Close() }() messages := []*Message{} for rows.Next() { msg := &Message{} msg.SetDB(u.db) err = rows.Scan( &msg.ID, &msg.Timestamp, &msg.FromUserID, &msg.FromNick, &msg.Target, &msg.Type, &msg.Body, &msg.Meta, &msg.CreatedAt, ) if err != nil { return nil, err } messages = append(messages, msg) } return messages, rows.Err() }