package service import ( "context" "encoding/json" "fmt" "github.com/google/uuid" "github.com/jackc/pgx/v5/pgxpool" "github.com/rs/zerolog" "github.com/gosec/gsc-ops-api/pkg/types" ) // PersonalAgentService handles personal agent config operations type PersonalAgentService struct { pool *pgxpool.Pool logger zerolog.Logger } // NewPersonalAgentService creates a new personal agent service func NewPersonalAgentService(pool *pgxpool.Pool, logger zerolog.Logger) *PersonalAgentService { return &PersonalAgentService{ pool: pool, logger: logger.With().Str("service", "personal_agent").Logger(), } } // GetConfig gets a user's personal agent config func (s *PersonalAgentService) GetConfig(ctx context.Context, userID, tenantID uuid.UUID) (*types.UserAgentConfig, error) { var c types.UserAgentConfig var configBytes []byte err := s.pool.QueryRow(ctx, `SELECT id, user_id, tenant_id, config, created_at, updated_at FROM admin.user_agent_configs WHERE user_id = $1 AND tenant_id = $2`, userID, tenantID). Scan(&c.ID, &c.UserID, &c.TenantID, &configBytes, &c.CreatedAt, &c.UpdatedAt) if err != nil { return nil, fmt.Errorf("not found: %w", err) } c.Config = json.RawMessage(configBytes) return &c, nil } // UpsertConfig creates or updates a user's personal agent config func (s *PersonalAgentService) UpsertConfig(ctx context.Context, req *types.UserAgentConfigUpsert) (*types.UserAgentConfig, error) { var c types.UserAgentConfig var configBytes []byte err := s.pool.QueryRow(ctx, `INSERT INTO admin.user_agent_configs (user_id, tenant_id, config) VALUES ($1, $2, $3) ON CONFLICT (user_id, tenant_id) DO UPDATE SET config = EXCLUDED.config, updated_at = NOW() RETURNING id, user_id, tenant_id, config, created_at, updated_at`, req.UserID, req.TenantID, req.Config). Scan(&c.ID, &c.UserID, &c.TenantID, &configBytes, &c.CreatedAt, &c.UpdatedAt) if err != nil { return nil, fmt.Errorf("upsert failed: %w", err) } c.Config = json.RawMessage(configBytes) s.logger.Info().Str("userId", req.UserID.String()).Str("tenantId", req.TenantID.String()).Msg("Upserted personal agent config") return &c, nil } // DeleteConfig deletes a user's personal agent config func (s *PersonalAgentService) DeleteConfig(ctx context.Context, userID, tenantID uuid.UUID) error { tag, err := s.pool.Exec(ctx, `DELETE FROM admin.user_agent_configs WHERE user_id = $1 AND tenant_id = $2`, userID, tenantID) if err != nil { return fmt.Errorf("delete failed: %w", err) } if tag.RowsAffected() == 0 { return fmt.Errorf("config not found") } s.logger.Info().Str("userId", userID.String()).Str("tenantId", tenantID.String()).Msg("Deleted personal agent config") return nil }