73077295a4
ci-cd-vm / ci-cd (push) Successful in 2m25s
Add an AI assist button to the Edit/New Group (大項) and Subcategory (小項) dialogs: the user enters a Chinese name, and the model refines the Chinese, translates it to English, and suggests the matching IRS Form 990 Part IX line. Suggestions surface in a confirm card; Apply fills the Chinese name, English name, and 990 line fields. Backend mirrors the existing expense-classification AI family but over the Form 990 line catalog: IExpenseCategoryAiService + base (catalog load, prompt, id validation) + Claude/Gemini providers + factory that picks the provider from ChurchProfile.AiProvider. New write-gated POST api/expense-categories/ai-suggest endpoint; sub-category requests pass the parent group + its 990 line to bias the choice. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
31 lines
1.0 KiB
C#
31 lines
1.0 KiB
C#
namespace ROLAC.API.Services.Ai;
|
|
|
|
/// <summary>Selects the active category-AI provider per request from <c>ChurchProfile.AiProvider</c>.</summary>
|
|
public interface IExpenseCategoryAiServiceFactory
|
|
{
|
|
Task<IExpenseCategoryAiService> ResolveAsync(CancellationToken ct = default);
|
|
}
|
|
|
|
public sealed class ExpenseCategoryAiServiceFactory : IExpenseCategoryAiServiceFactory
|
|
{
|
|
private readonly IChurchAiConfigProvider _config;
|
|
private readonly ClaudeExpenseCategoryAiService _claude;
|
|
private readonly GeminiExpenseCategoryAiService _gemini;
|
|
|
|
public ExpenseCategoryAiServiceFactory(
|
|
IChurchAiConfigProvider config,
|
|
ClaudeExpenseCategoryAiService claude,
|
|
GeminiExpenseCategoryAiService gemini)
|
|
{
|
|
_config = config;
|
|
_claude = claude;
|
|
_gemini = gemini;
|
|
}
|
|
|
|
public async Task<IExpenseCategoryAiService> ResolveAsync(CancellationToken ct = default)
|
|
{
|
|
var cfg = await _config.GetAsync(ct);
|
|
return cfg.Provider.Equals("Gemini", StringComparison.OrdinalIgnoreCase) ? _gemini : _claude;
|
|
}
|
|
}
|