package notification import ( "context" "database/sql" "errors" "fmt" "time" ) var ErrNotFound = fmt.Errorf("notification not found") type Notification struct { ID int64 `json:"id"` VolunteerID int64 `json:"volunteer_id"` Message string `json:"message"` Read bool `json:"read"` CreatedAt time.Time `json:"created_at"` } type Store struct { db *sql.DB } func NewStore(db *sql.DB) *Store { return &Store{db: db} } func (s *Store) Create(ctx context.Context, volunteerID int64, message string) (*Notification, error) { res, err := s.db.ExecContext(ctx, `INSERT INTO notifications (volunteer_id, message) VALUES (?, ?)`, volunteerID, message, ) if err != nil { return nil, fmt.Errorf("insert notification: %w", err) } id, _ := res.LastInsertId() return s.GetByID(ctx, id) } func (s *Store) GetByID(ctx context.Context, id int64) (*Notification, error) { n := &Notification{} var createdAt string err := s.db.QueryRowContext(ctx, `SELECT id, volunteer_id, message, read, created_at FROM notifications WHERE id = ?`, id, ).Scan(&n.ID, &n.VolunteerID, &n.Message, &n.Read, &createdAt) if errors.Is(err, sql.ErrNoRows) { return nil, ErrNotFound } if err != nil { return nil, fmt.Errorf("get notification: %w", err) } n.CreatedAt, _ = time.Parse("2006-01-02 15:04:05", createdAt) return n, nil } func (s *Store) ListForVolunteer(ctx context.Context, volunteerID int64) ([]Notification, error) { rows, err := s.db.QueryContext(ctx, `SELECT id, volunteer_id, message, read, created_at FROM notifications WHERE volunteer_id = ? ORDER BY created_at DESC`, volunteerID, ) if err != nil { return nil, fmt.Errorf("list notifications: %w", err) } defer rows.Close() var notifications []Notification for rows.Next() { var n Notification var createdAt string if err := rows.Scan(&n.ID, &n.VolunteerID, &n.Message, &n.Read, &createdAt); err != nil { return nil, err } n.CreatedAt, _ = time.Parse("2006-01-02 15:04:05", createdAt) notifications = append(notifications, n) } return notifications, rows.Err() } func (s *Store) MarkRead(ctx context.Context, id, volunteerID int64) (*Notification, error) { result, err := s.db.ExecContext(ctx, `UPDATE notifications SET read = 1 WHERE id = ? AND volunteer_id = ?`, id, volunteerID, ) if err != nil { return nil, fmt.Errorf("mark read: %w", err) } affected, _ := result.RowsAffected() if affected == 0 { return nil, ErrNotFound } return s.GetByID(ctx, id) }