- Backend: Email producer (LavinMQ), EmailService interface - Backend: CRUD API for email_templates and email_settings - Backend: avatar_url field in users table + UpdateMyProfile support - Backend: StorageService for pre-signed URLs - NestJS: Email consumer with Nodemailer and Handlebars - Frontend: Email Templates admin pages (list/edit) - Frontend: Updated profileApi.uploadAvatar with pre-signed URL flow - Frontend: New /post-job public page (company registration + job creation wizard) - Migrations: 027_create_email_system.sql, 028_add_avatar_url_to_users.sql
51 lines
1.3 KiB
Go
51 lines
1.3 KiB
Go
package services
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"encoding/json"
|
|
"fmt"
|
|
)
|
|
|
|
type SettingsService struct {
|
|
db *sql.DB
|
|
}
|
|
|
|
func NewSettingsService(db *sql.DB) *SettingsService {
|
|
return &SettingsService{db: db}
|
|
}
|
|
|
|
// GetSettings retrieves a JSON setting by key. Returns nil if not found.
|
|
func (s *SettingsService) GetSettings(ctx context.Context, key string) (json.RawMessage, error) {
|
|
var value []byte
|
|
err := s.db.QueryRowContext(ctx, "SELECT value FROM system_settings WHERE key = $1", key).Scan(&value)
|
|
if err == sql.ErrNoRows {
|
|
return nil, nil // Not found
|
|
}
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get setting %s: %w", key, err)
|
|
}
|
|
|
|
return json.RawMessage(value), nil
|
|
}
|
|
|
|
// SaveSettings saves a JSON setting. Updates if exists.
|
|
func (s *SettingsService) SaveSettings(ctx context.Context, key string, value interface{}) error {
|
|
jsonBytes, err := json.Marshal(value)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to marshal setting value: %w", err)
|
|
}
|
|
|
|
query := `
|
|
INSERT INTO system_settings (key, value, updated_at)
|
|
VALUES ($1, $2, NOW())
|
|
ON CONFLICT (key) DO UPDATE
|
|
SET value = EXCLUDED.value, updated_at = NOW()
|
|
`
|
|
_, err = s.db.ExecContext(ctx, query, key, jsonBytes)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to save setting %s: %w", key, err)
|
|
}
|
|
|
|
return nil
|
|
}
|