Files
chat/internal/models/user.go
clawbot b21508cecc Add complete database schema and ORM models
Schema (002_tables.sql):
- users: accounts with nick, password hash, timestamps
- auth_tokens: per-device tokens with expiry, linked to users
- channels: chat rooms with topic and mode flags
- channel_members: membership with per-user modes (+o, +v)
- messages: channel/DM history with structured JSON meta
- message_queue: per-user pending delivery queue
- sessions: server-held session state with idle timeout
- server_links: federation peer configuration

Models (internal/models/):
- All models embed Base for database access
- Relation methods on models: User.Channels(), User.QueuedMessages(),
  Channel.Members(), Channel.RecentMessages(), ChannelMember.User(),
  ChannelMember.Channel(), AuthToken.User(), Session.User()
- IDs are UUIDs (TEXT), not auto-increment integers
- JSON tags use camelCase per lint rules

All tables verified: migrations apply cleanly, 0 lint issues.
2026-02-09 14:54:35 -08:00

93 lines
1.9 KiB
Go

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() }()
var 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() }()
var 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()
}