8a4029058b
Add demo dashboard settings table and CRUD API * Add demo dashboard settings table and CRUD API - Migration 00000000000123: create demoDashboardSettings table (id, guid, key, value JSONB, isDeleted, timestamps) - SQLC queries and repository for create, list, listByGuid, get, update, soft delete - OpenAPI paths and schemas in queryAPI.yaml; regenerate api.gen.go (embedded spec) - Handlers in api/queryAPI/demodashboardsettings.go; ConfigProvider GetDBQueries for repo access - Unit tests for demo dashboard settings CRUD * Fix sqlc-generated demo dashboard setting types Align demo dashboard settings handlers with sqlc output (DemoDashboardSetting model + pointer slices) so CI codegen/build succeeds. * Fix CI gosec and gofmt issues - Suppress gosec G115 for TotalCount len->int32 cast (consistent with other list endpoints) - gofmt mock GetDBQueries() in test helpers * gofmt query API demo settings * Tighten demo dashboard settings OpenAPI constraints * Regenerate query API embedded spec * refactor: generic UI settings (table, API, service) and three-layer architecture - Replace demo-dashboard-settings with generic UI settings: - Table uiSettings with namespace (was guid), key, value JSONB; UNIQUE(namespace, key) - Migration 123: create_ui_settings (single migration, no rename) - OpenAPI: /ui-settings, UISettingsService, UISetting schemas with namespace - API types and handlers: CreateUISetting, ListUISettings, GetUISetting, UpdateUISetting, DeleteUISetting - Add service layer (architecture fix): - internal/uisettings: Service with Create, List, ListByNamespace, Get, Update, SoftDelete - Controllers call s.svc.UISettings only; remove GetDBQueries from queryAPI ConfigProvider - Wire UISettings in Services, main.go, and testutils - Repository: uisettings.sql + uisettings.sql.go, UISetting model; remove demodashboardsettings - Controller: uisettings.go (replaces demodashboardsettings.go), ErrNotFound from uisettings package - Tests: uisettings_test.go with namespace-based list/cre… * Add UISetting model and generated queries for uiSettings table - models.go: add UISetting struct (sqlc 1.30.0) - uisettings.sql.go: generated CRUD for ui_settings feature Made-with: Cursor * Use repository.UiSetting to match sqlc-generated type - service and API use repository.UiSetting (sqlc struct name for uiSettings table) - uisettings.sql.go: keep CreateUISetting/GetUISetting etc. from query names, return *UiSetting - Fixes Docker/CI build undefined repository.UISetting * Fix import formatting for golangci-lint * Lint fix * uisettings list test * tests fixes * Merge main: resolve api.gen.go conflicts (UI settings + DeleteDocument) * Doc updates and elimination of index redundancy Approved-by: Jay Brown
97 lines
2.9 KiB
Go
97 lines
2.9 KiB
Go
// Package uisettings provides generic UI key-value settings storage (e.g. demo dashboard state,
|
|
// feature flags, saved filters). Callers partition data via namespace (e.g. "demo-dashboard:{userId}").
|
|
// It handles CRUD and soft-delete semantics; value is stored as JSON.
|
|
package uisettings
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"queryorchestration/internal/database/repository"
|
|
"queryorchestration/internal/serviceconfig"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/jackc/pgx/v5"
|
|
)
|
|
|
|
// Service provides UI settings operations.
|
|
type Service struct {
|
|
cfg serviceconfig.ConfigProvider
|
|
}
|
|
|
|
// New creates a new UI settings service.
|
|
func New(cfg serviceconfig.ConfigProvider) *Service {
|
|
return &Service{cfg: cfg}
|
|
}
|
|
|
|
// Create creates a new UI setting.
|
|
func (s *Service) Create(ctx context.Context, namespace, key string, value []byte) (*repository.UiSetting, error) {
|
|
row, err := s.cfg.GetDBQueries().CreateUISetting(ctx, &repository.CreateUISettingParams{
|
|
Namespace: namespace,
|
|
Key: key,
|
|
Value: value,
|
|
})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("create UI setting: %w", err)
|
|
}
|
|
return row, nil
|
|
}
|
|
|
|
// List returns all non-deleted UI settings.
|
|
func (s *Service) List(ctx context.Context) ([]*repository.UiSetting, error) {
|
|
rows, err := s.cfg.GetDBQueries().ListUISettings(ctx)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("list UI settings: %w", err)
|
|
}
|
|
return rows, nil
|
|
}
|
|
|
|
// ListByNamespace returns non-deleted UI settings for the given namespace.
|
|
func (s *Service) ListByNamespace(ctx context.Context, namespace string) ([]*repository.UiSetting, error) {
|
|
rows, err := s.cfg.GetDBQueries().ListUISettingsByNamespace(ctx, namespace)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("list UI settings by namespace: %w", err)
|
|
}
|
|
return rows, nil
|
|
}
|
|
|
|
// Get returns a single setting by id, or ErrNotFound if not found or soft-deleted.
|
|
func (s *Service) Get(ctx context.Context, id uuid.UUID) (*repository.UiSetting, error) {
|
|
row, err := s.cfg.GetDBQueries().GetUISetting(ctx, id)
|
|
if err != nil {
|
|
if errors.Is(err, pgx.ErrNoRows) {
|
|
return nil, ErrNotFound
|
|
}
|
|
return nil, fmt.Errorf("get UI setting: %w", err)
|
|
}
|
|
if row == nil {
|
|
return nil, ErrNotFound
|
|
}
|
|
return row, nil
|
|
}
|
|
|
|
// Update updates a setting's value. Returns ErrNotFound if the setting does not exist or is soft-deleted.
|
|
func (s *Service) Update(ctx context.Context, id uuid.UUID, value []byte) error {
|
|
err := s.cfg.GetDBQueries().UpdateUISetting(ctx, &repository.UpdateUISettingParams{
|
|
ID: id,
|
|
Value: value,
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("update UI setting: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// SoftDelete soft-deletes a setting by id.
|
|
func (s *Service) SoftDelete(ctx context.Context, id uuid.UUID) error {
|
|
err := s.cfg.GetDBQueries().SoftDeleteUISetting(ctx, id)
|
|
if err != nil {
|
|
return fmt.Errorf("soft delete UI setting: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// ErrNotFound is returned when a setting is not found or is soft-deleted.
|
|
var ErrNotFound = errors.New("UI setting not found")
|