Use Case 022: Advanced Cross-Entity Search and Saved Searches

Overview

Property Value
Use Case ID UC-022
Use Case Name Advanced Cross-Entity Search and Saved Searches
Module Administration — Advanced Search
Priority Medium
Status Implemented
Version 1.0
Last Updated April 3, 2026

Description

This use case describes how administrators use the Advanced Search module to perform multi-criteria searches across trial users and admin users, save frequently-used search configurations for quick reuse, and export search results to CSV. The module provides a rich search interface with filters for name, email, company, status, date ranges, and more — all combined with AND logic. Users can save and load named search criteria, enabling quick access to common queries like "expired trials needing follow-up" or "inactive admin accounts."

Actors

Actor Description Role
Administrator Authenticated admin user performing searches Primary
System Application Manager search engine Supporting

Preconditions

  1. Application Manager is running and accessible
  2. User authenticated with valid session
  3. Trial users and/or admin users exist in the system
  4. SavedSearches table exists in Identity database

Postconditions

Success Postconditions

  1. Search results displayed with pagination and sorting
  2. Saved search persisted with name, description, and criteria JSON
  3. CSV export downloaded with timestamped filename
  4. Search criteria available for future reuse

Failure Postconditions

  1. Invalid search criteria returns validation error
  2. Failed search logged with error details
  3. Duplicate saved search name returns descriptive error
  4. Export failure returns 500 with error message

Triggers

  • Administrator navigates to Advanced Search module
  • Administrator needs to find users matching specific criteria
  • Administrator wants to export user data for reporting
  • Administrator saves a complex search for recurring use
  • Administrator loads a previously saved search
sequenceDiagram actor Admin as Administrator participant UI as Search Interface participant Ctrl as AdvancedSearchController participant Med as MediatR participant Handler as SearchTrialUsersQueryHandler participant DB as Identity DB Note over Admin,DB: Advanced Trial User Search Flow Admin->>UI: Navigate to /advanced-search/trial-users UI->>Admin: Display search form with criteria fields Admin->>UI: Enter criteria (name, email, company, status, dates) Admin->>UI: Click "Search" UI->>Ctrl: POST /advanced-search/trial-users/search (JSON body) Ctrl->>Med: Send(SearchTrialUsersQuery) Med->>Handler: Handle(query) Handler->>DB: Build LINQ query with EF.Functions.Like filters Handler->>DB: Count total matches Handler->>DB: Apply sorting and pagination DB->>Handler: Paginated TrialUser results Handler->>Med: TrialUserSearchResultDto Med->>Ctrl: Result with users, totalCount, pagination Ctrl->>UI: JSON { success: true, data: results } UI->>Admin: Display results table with pagination controls Admin->>UI: Click "Export to CSV" UI->>Ctrl: POST /advanced-search/trial-users/export Ctrl->>Med: Send(SearchTrialUsersQuery) with PageSize=10000 Med->>Handler: Handle(query) Handler->>DB: Execute full result query DB->>Handler: All matching users (up to 10,000) Handler->>Ctrl: SearchResultDto Ctrl->>Ctrl: CsvExportService.ExportSearchResultsToCsvAsync() Ctrl->>UI: File download (trial_users_search_YYYYMMDD_HHMMSS.csv) UI->>Admin: CSV file downloaded

Alternative Flows

Alt-1: Save Search Criteria

Trigger: Administrator wants to save current search for reuse

Flow:

  1. Administrator performs a search with specific criteria
  2. Administrator clicks "Save Search" button
  3. UI displays save dialog with Name (required) and Description (optional) fields
  4. Administrator enters name (e.g., "Expired Trials — Q1 2026") and description
  5. UI sends POST /advanced-search/save with name, description, searchType, criteria
  6. Controller extracts UserId from authentication claims
  7. Handler validates name uniqueness for user
  8. Handler serializes criteria to JSON and creates SavedSearch entity
  9. Handler persists to database with CreatedAt timestamp and UseCount=0
  10. UI shows success: "Search 'Expired Trials — Q1 2026' saved successfully"

Trigger: Administrator wants to apply a previously saved search

Flow:

  1. Administrator clicks "Load Saved Search" button
  2. UI sends GET /advanced-search/saved?searchType=TrialUsers
  3. Controller retrieves user's saved searches filtered by type
  4. Handler queries SavedSearches ordered by: favorites first, then most recently used
  5. UI displays saved search list with name, description, and usage stats
  6. Administrator clicks a saved search
  7. UI populates search form with the saved criteria
  8. Administrator clicks "Search" to execute (or modifies criteria first)

Trigger: Administrator needs to search admin/application users

Flow:

  1. Administrator navigates to /advanced-search/users
  2. UI shows admin user search form with fields: Full Name, Email, Username, Status, Role, Email Verified, date ranges
  3. Administrator enters criteria and searches
  4. POST /advanced-search/users/search with SearchAdminUsersQuery
  5. Handler joins with roles for role-based filtering
  6. Results displayed with Name, Email, Username, Status, Verified, Roles columns
  7. Export available via POST /advanced-search/users/export

Alt-4: Duplicate Saved Search Name

Trigger: Administrator saves search with name that already exists

Flow:

  1. Administrator enters a search name that duplicates an existing one
  2. Handler finds existing SavedSearch with same name for this user
  3. Handler throws InvalidOperationException: "A saved search with the name 'X' already exists"
  4. Controller returns BadRequest with error message
  5. UI displays error, administrator can choose a different name

Alt-5: Empty Search Results

Trigger: No users match the given criteria

Flow:

  1. Administrator enters restrictive criteria
  2. Search executes and returns TotalCount = 0
  3. UI displays "Found 0 trial user(s) matching your criteria"
  4. Results table shows empty state
  5. Administrator adjusts criteria and searches again

Business Rules

Search Rules

  • BR-022-01: All search criteria combined with AND logic
  • BR-022-02: Text fields use case-insensitive partial matching (LIKE %value%)
  • BR-022-03: Date range filters use inclusive boundaries
  • BR-022-04: Default sort: newest first (CreatedAt descending)
  • BR-022-05: Pagination defaults: PageNumber=1, configurable PageSize

Saved Search Rules

  • BR-022-06: Saved search names must be unique per user (not globally)
  • BR-022-07: Each saved search belongs to exactly one user (no sharing)
  • BR-022-08: Search types supported: "TrialUsers", "AdminUsers"
  • BR-022-09: Criteria stored as JSON dictionary (key-value pairs)
  • BR-022-10: RecordUsage() updates LastUsedAt and increments UseCount on execution
  • BR-022-11: Saved searches ordered by: IsFavorite (desc), LastUsedAt (desc), CreatedAt (desc)
  • BR-022-12: Users can toggle IsFavorite for quick access

Export Rules

  • BR-022-13: Maximum export size: 10,000 records per CSV
  • BR-022-14: CSV filenames include UTC timestamp: trial_users_search_YYYYMMDD_HHMMSS.csv
  • BR-022-15: Export uses same search criteria as interactive search
  • BR-022-16: Export endpoints protected with anti-forgery tokens

Authorization Rules

  • BR-022-17: All search endpoints require authentication ([Authorize])
  • BR-022-18: UserId for saved searches determined from ClaimTypes.NameIdentifier

Data Model

SavedSearch Entity

Field Type Description
Id Guid (PK) Unique identifier
UserId Guid Owner user ID
Name string (200) Display name, unique per user
Description string? (500) Optional description
SearchType string (50) "TrialUsers" or "AdminUsers"
CriteriaJson text Serialized search criteria JSON
CreatedAt DateTime Creation timestamp
LastUsedAt DateTime? Most recent execution timestamp
UseCount int Total execution count
IsFavorite bool Quick-access flag

Search Criteria Fields — Trial Users

Field Type Description
FullName string? Partial match on full name
Email string? Partial match on email
CompanyName string? Partial match on company
JobTitle string? Partial match on job title
IsActive bool? Active/inactive filter
TrialStartDateFrom/To DateTime? Trial start date range
TrialEndDateFrom/To DateTime? Trial end date range
TrialStatus enum? Active, ExpiringSoon, Expired
EmailVerified bool? Verification status

Search Criteria Fields — Admin Users

Field Type Description
FullName string? Partial match on full name
Email string? Partial match on email
Username string? Partial match on username
IsActive bool? Active/inactive filter
CreatedDateFrom/To DateTime? Account creation date range
LastLoginFrom/To DateTime? Last login date range
RoleId Guid? Filter by assigned role
EmailVerified bool? Verification status

API Endpoints

Method Route Description
GET /advanced-search/trial-users Trial user search page
GET /advanced-search/users Admin user search page
POST /advanced-search/trial-users/search Execute trial user search
POST /advanced-search/users/search Execute admin user search
POST /advanced-search/trial-users/export Export trial user results to CSV
POST /advanced-search/users/export Export admin user results to CSV
POST /advanced-search/save Save search criteria
GET /advanced-search/saved Retrieve saved searches

Test Scenarios

ID Scenario Expected Result
TS-022-01 Search trial users by email partial match Returns matching users with pagination
TS-022-02 Search with no criteria Returns all users (paginated)
TS-022-03 Search with multiple criteria (AND logic) Returns only users matching ALL criteria
TS-022-04 Save search with unique name SavedSearch created with correct metadata
TS-022-05 Save search with duplicate name InvalidOperationException thrown
TS-022-06 Get saved searches for user Returns only user's searches, ordered correctly
TS-022-07 Get saved searches filtered by type Returns only matching search type
TS-022-08 Export trial users to CSV File returned with correct content type
TS-022-09 Search admin users by role Returns users with specified role
TS-022-10 SavedSearch.RecordUsage() LastUsedAt updated, UseCount incremented
TS-022-11 SavedSearch.ToggleFavorite() IsFavorite toggled
TS-022-12 Search with invalid model state Returns BadRequest with ModelState errors

Dependencies

  • MediatR (CQRS command/query handling)
  • Entity Framework Core with IdentityDbContext
  • CsvExportService (CSV generation via CsvHelper)
  • ASP.NET Core Authentication (ClaimTypes.NameIdentifier for user identity)