Files
flatrender/services/notification/internal/db/channels.go
T

91 lines
3.5 KiB
Go
Raw Normal View History

package db
import (
"context"
"encoding/json"
"github.com/flatrender/notification-svc/internal/models"
"github.com/google/uuid"
"github.com/jackc/pgx/v5"
)
// ── Channel provider config ──────────────────────────────────────────────────
func (s *Store) GetChannelConfigs(ctx context.Context, tenantID uuid.UUID) ([]*models.ChannelConfig, error) {
rows, err := s.pool.Query(ctx,
`SELECT tenant_id, channel, settings, enabled, updated_at
FROM notification.channel_config WHERE tenant_id = $1 ORDER BY channel`, tenantID)
if err != nil {
return nil, err
}
defer rows.Close()
var out []*models.ChannelConfig
for rows.Next() {
c := &models.ChannelConfig{}
var raw []byte
if err := rows.Scan(&c.TenantID, &c.Channel, &raw, &c.Enabled, &c.UpdatedAt); err != nil {
return nil, err
}
_ = json.Unmarshal(raw, &c.Settings)
out = append(out, c)
}
return out, rows.Err()
}
func (s *Store) GetChannelConfig(ctx context.Context, tenantID uuid.UUID, channel string) (*models.ChannelConfig, error) {
c := &models.ChannelConfig{}
var raw []byte
err := s.pool.QueryRow(ctx,
`SELECT tenant_id, channel, settings, enabled, updated_at
FROM notification.channel_config WHERE tenant_id = $1 AND channel = $2`, tenantID, channel).
Scan(&c.TenantID, &c.Channel, &raw, &c.Enabled, &c.UpdatedAt)
if err == pgx.ErrNoRows {
return nil, nil
}
if err != nil {
return nil, err
}
_ = json.Unmarshal(raw, &c.Settings)
return c, nil
}
func (s *Store) UpsertChannelConfig(ctx context.Context, tenantID uuid.UUID, channel string, settings map[string]any, enabled bool) error {
raw, _ := json.Marshal(settings)
_, err := s.pool.Exec(ctx,
`INSERT INTO notification.channel_config (tenant_id, channel, settings, enabled, updated_at)
VALUES ($1, $2, $3, $4, NOW())
ON CONFLICT (tenant_id, channel)
DO UPDATE SET settings = EXCLUDED.settings, enabled = EXCLUDED.enabled, updated_at = NOW()`,
tenantID, channel, raw, enabled)
return err
}
// ── Email template lookup ────────────────────────────────────────────────────
func (s *Store) GetEmailTemplate(ctx context.Context, code, locale string) (*models.NotificationTemplate, error) {
t := &models.NotificationTemplate{}
err := s.pool.QueryRow(ctx,
`SELECT id, code, channel, locale, subject, body_text, body_html, is_active
FROM notification.notification_templates
WHERE code = $1 AND channel = 'Email' AND locale = $2 AND is_active = TRUE
LIMIT 1`, code, locale).
Scan(&t.ID, &t.Code, &t.Channel, &t.Locale, &t.Subject, &t.BodyText, &t.BodyHTML, &t.IsActive)
if err == pgx.ErrNoRows {
return nil, nil
}
return t, err
}
// ── Delivery log ─────────────────────────────────────────────────────────────
func (s *Store) LogDelivery(ctx context.Context, tenantID, userID uuid.UUID, channel, recipient string,
subject, provider, providerMsgID, status, errMsg *string) error {
_, err := s.pool.Exec(ctx,
`INSERT INTO notification.notification_deliveries
(tenant_id, user_id, channel, recipient, subject, provider, provider_message_id, status, error_message, sent_at)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, NOW())`,
tenantID, userID, channel, recipient, subject, provider, providerMsgID, status, errMsg)
return err
}