package postgres import ( "context" "database/sql" "git.gobha.me/xcaliber/chat-switchboard/models" ) type PolicyStore struct{} func NewPolicyStore() *PolicyStore { return &PolicyStore{} } // Get returns a policy value by key. Falls back to PolicyDefaults if not in DB. func (s *PolicyStore) Get(ctx context.Context, key string) (string, error) { var value string err := DB.QueryRowContext(ctx, "SELECT value FROM platform_policies WHERE key = $1", key).Scan(&value) if err == sql.ErrNoRows { if def, ok := models.PolicyDefaults[key]; ok { return def, nil } return "", nil } return value, err } // GetBool returns a policy value as a boolean. func (s *PolicyStore) GetBool(ctx context.Context, key string) (bool, error) { val, err := s.Get(ctx, key) if err != nil { return false, err } return val == "true", nil } // Set upserts a policy value. func (s *PolicyStore) Set(ctx context.Context, key, value, updatedBy string) error { _, err := DB.ExecContext(ctx, ` INSERT INTO platform_policies (key, value, updated_by, updated_at) VALUES ($1, $2, $3, NOW()) ON CONFLICT (key) DO UPDATE SET value = $2, updated_by = $3, updated_at = NOW()`, key, value, updatedBy) return err } // GetAll returns all platform policies, merged with defaults. func (s *PolicyStore) GetAll(ctx context.Context) (map[string]string, error) { result := make(map[string]string) // Start with defaults for k, v := range models.PolicyDefaults { result[k] = v } // Override with DB values rows, err := DB.QueryContext(ctx, "SELECT key, value FROM platform_policies") if err != nil { return result, err // return defaults on error } defer rows.Close() for rows.Next() { var k, v string if err := rows.Scan(&k, &v); err != nil { continue } result[k] = v } return result, rows.Err() }