2368764251
Core: - IEspoCrmClient.ListCasesForContactAsync (paged where[]=linkedWith query) - EspoListResponse<T> generic envelope for /list endpoints - IMatchingService + MatchingService: EmailAddress/search → Contact → Account → recent 5 Cases. MemoryCache 10-min TTL; caches null and ambiguous results too. Returns null for 0 matches, IsAmbiguous=true for 2+, populated MatchResult for exactly 1. - MatchResult DTO with Contact / Account / RecentCases / IsAmbiguous UI: - ReadingPaneView (WPF UserControl, RTL): 6 states — Empty / Loading / Match / NoMatch / Ambiguous / Error — switched via Visibility bindings - ReadingPaneViewModel: state machine, FileRequested + OpenInBrowserRequested events, Reset()/LoadAsync() with cancellation chain (every selection cancels the previous lookup) Host: - ExplorerSelectionHandler: subscribes to Outlook.Explorer.SelectionChange, 200ms debounce via Timer, dedupes by last sender, marshals to WPF dispatcher before reading COM state - SidebarController: attaches a CustomTaskPane per Explorer (ElementHost wrapping ReadingPaneView), tracks bindings by COM identity, unhooks on Explorer.Close. Sidebar defers attach until CRM client is configured (subscribes to CrmClientChanged) - AddInHost: MatchingService field, MemoryCache shared across lookups, InitializeSidebar(taskPanes) invoked from ThisAddIn_Startup Core/UI/Tests green (38 tests passing); VSTO host still needs VS Installer Repair locally. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
19 lines
617 B
C#
19 lines
617 B
C#
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using MarcusLaw.OutlookAddin.Core.Models;
|
|
|
|
namespace MarcusLaw.OutlookAddin.Core.Services
|
|
{
|
|
public interface IMatchingService
|
|
{
|
|
/// <summary>
|
|
/// Looks up the contact/account/recent-cases bundle for a sender
|
|
/// email address. Returns null when there is no unique Contact match
|
|
/// (0 or 2+ candidates). Results are cached for 10 minutes.
|
|
/// </summary>
|
|
Task<MatchResult?> LookupAsync(string senderEmail, CancellationToken cancellationToken = default);
|
|
|
|
void Invalidate(string senderEmail);
|
|
}
|
|
}
|