Skip to main content

Search & Filters — Technical Documentation

Last updated: February 2026


Table of Contents

  1. Overview
  2. Architecture
  3. Repository Map
  4. Core Flows
  5. FilterType Enum System
  6. API Endpoints
  7. Services & Business Logic
  8. Frontend Implementation
  9. Configuration
  10. Integration Points

1. Overview

Search & Filters provides prospect and company search with a type-safe enum-based filter system. The FilterType enum maps to metadata (label, icon, category), providing centralized filter definitions. The backend exposes search endpoints with filter parameters, autocomplete lookups, and paginated results. Frontend uses React Query hooks with the FilterType system for consistent UI rendering.

Primary repos: data-admin (frontend filter UI, FilterType system) and sopromasterdata (search API endpoints, autocomplete lookups).


2. Architecture


3. Repository Map

RepositoryLayerKey Files
data-adminFilterType Enumsrc/types/enums/FilterType.ts
data-adminFilter Metadatasrc/types/enums/FilterType.ts (FILTER_METADATA object)
data-adminMetadata Helperssrc/helpers/filterMetadataHelpers.ts
data-adminFilter Hookssrc/hooks/useFilter.ts, useFilterItems.ts, usePinnedFilters.ts
data-adminSearch Pagesrc/pages/search/
data-adminSearch Queriessrc/api/search.queries.ts
data-adminUtils Queriessrc/api/utils.queries.ts
data-adminForm-to-Paramssrc/utils/formToFilterParams.ts
data-adminEnum Utilssrc/utils/enumUtils.ts
sopromasterdataProspect SearchAPI/SoProMasterDBAPI/Controllers/ProspectController.cs
sopromasterdataCompany SearchAPI/SoProMasterDBAPI/Controllers/CompanyController.cs
sopromasterdataUtils/AutocompleteAPI/SoProMasterDBAPI/Controllers/UtilsController.cs
sopromasterdataSearch ServiceSearchServices/SearchService.cs

4. Core Flows

4.1 Search with Filters

4.2 Autocomplete Flow


5. FilterType Enum System

FilterType Enum

Location: src/types/enums/FilterType.ts

export enum FilterType {
COMPANY_NAME = "companyName",
INDUSTRY = "industry",
COMPANY_SIZE = "companySize",
REVENUE = "revenue",
JOB_TITLE = "jobTitle",
SENIORITY = "seniority",
DEPARTMENT = "department",
COUNTRY = "country",
REGION = "region",
CITY = "city",
TECHNOLOGY = "technology",
TECHNOLOGY_CATEGORY = "technologyCategory",
// ... additional filter types
}

FILTER_METADATA

Each FilterType maps to metadata:

export const FILTER_METADATA: Record<FilterType, FilterMetadata> = {
[FilterType.COMPANY_NAME]: {
label: "Company Names",
icon: "BuildingOfficeIcon",
category: "Company",
description: "Filter by company name",
},
[FilterType.INDUSTRY]: {
label: "Industries",
icon: "BriefcaseIcon",
category: "Company",
description: "Filter by industry classification",
},
// ... metadata for each filter type
};

Helper Functions

Location: src/helpers/filterMetadataHelpers.ts

// Get metadata for a filter
getFilterMetadata(FilterType.COMPANY_NAME);
// → { label: "Company Names", icon: "BuildingOfficeIcon", ... }

// Check if a filter is active
isFilterActive(formData, FilterType.INDUSTRY);
// → true/false

// Get all active filters with metadata
getActiveFilters(formData);
// → [{ type: FilterType.INDUSTRY, metadata: {...}, value: "Technology" }]

Why Enum-Based?

The previous string-based system had:

  • No type safety (typos caused silent failures)
  • Manual icon mapping in each component
  • Inconsistent labels across the UI
  • Maintenance headaches when adding filters

The enum-based system provides:

  • Type safety — compiler catches invalid filter references
  • Centralized metadata — labels, icons, categories defined once
  • Consistent UI — every filter rendered the same way
  • Easy extension — add a filter type + metadata entry

6. API Endpoints

MethodEndpointDescription
GET/api/Prospects/SearchSearch prospects with filters

Query Parameters:

ParameterTypeDescription
qstringFree-text search query
industrystring[]Industry filter values
jobTitlestring[]Job title filter values
senioritystring[]Seniority level values
countrystring[]Country filter values
companySizestring[]Company size ranges
revenuestring[]Revenue ranges
technologystring[]Technology filter values
pageintPage number (1-based)
pageSizeintResults per page
MethodEndpointDescription
GET/api/Companies/SearchSearch companies with filters
GET/api/Companies/{id}Get company detail

Utils / Autocomplete

MethodEndpointDescription
GET/api/Utils/AutocompleteAutocomplete suggestions for filter values
GET/api/Utils/IndustriesList all industries
GET/api/Utils/TechnologiesList all technologies
GET/api/Utils/CountriesList all countries
GET/api/Utils/RevenueRangesList revenue range options
GET/api/Utils/CompanySizesList company size options
GET/api/Utils/SenioritiesList seniority levels

7. Services & Business Logic

Backend Services

SearchService

Location: SearchServices/SearchService.cs
Interface: ISearchService

MethodDescription
SearchProspectsAsync()Full-text + filter search against prospect database
SearchCompaniesAsync()Company search with filter parameters
GetBreakdownAsync()Aggregated distribution of results by category

Frontend Hooks

useFilter

Location: src/hooks/useFilter.ts
Purpose: Manages filter state — adding, removing, and clearing individual filters.

useFilterItems

Location: src/hooks/useFilterItems.ts
Purpose: Fetches available filter options (used for dropdowns and autocomplete).

usePinnedFilters

Location: src/hooks/usePinnedFilters.ts
Purpose: Manages saved filter combinations for quick access.

useCompanySearch

Location: src/hooks/useCompanySearch.ts
Purpose: Encapsulates company search logic with debounced input.

Utility Functions

formToFilterParams

Location: src/utils/formToFilterParams.ts
Purpose: Converts React Hook Form data into API-compatible filter parameters.

// Transforms form state → URL query parameters
const params = formToFilterParams(formData);
// { industry: ["Technology"], seniority: ["VP", "Director"], country: ["UK"] }

enumUtils

Location: src/utils/enumUtils.ts
Purpose: Generic enum serialization/deserialization utilities.


8. Frontend Implementation

Component Structure

Import Pattern

import { FilterType, FILTER_METADATA } from "@enums";
import { getFilterMetadata, isFilterActive, getActiveFilters } from "@helpers/filterMetadataHelpers";
import { useFilter } from "@hooks/useFilter";
import { formToFilterParams } from "@utils/formToFilterParams";

9. Configuration

Frontend DI

Enum exports: src/types/enums/index.ts — barrel export for FilterType and FILTER_METADATA
Endpoints: src/api/endpoints.ts

endpoints: {
prospects: { search: "/Prospects/Search" },
companies: { search: "/Companies/Search", getById: "/Companies" },
utils: {
autocomplete: "/Utils/Autocomplete",
industries: "/Utils/Industries",
technologies: "/Utils/Technologies",
// ...
}
}

Backend DI

DataApi: API/SoProMasterDBAPI/Extensions/ApiServiceExtensions.cs

services.AddScoped<ISearchService, SearchService>();

10. Integration Points

Upstream (data flows in)

SourceDataMechanism
Prospect DatabaseProspect records for search indexingSQL Server queries
Company DatabaseCompany records with metadataSQL Server queries
Lookup TablesIndustries, technologies, locations, sizesUtils API endpoints
ClickHouseFast analytical queries for breakdownsDapper ClickHouse service

Downstream (data flows out)

TargetDataMechanism
Data Admin UISearch results, autocomplete suggestionsREST API → React Query
Audience ManagementFilter definitions reused for audience targetingShared FilterType system

Cross-Feature Dependencies

FeatureRelationship
Audience ManagementAudience targeting uses the same filter concepts
Verification PipelineVerification status appears as a searchable property
Campaign ManagementCampaign prospects are searchable with the same filters