feat: Users AI Chat multi-step workflows with CDT lookup and alias management

- Add eligibility_by_id and check_and_claim intents to internal chat
- New cdt-lookup.ts: keyword search against fee schedule JSON (no LLM)
- New internal-chat-workflow.ts: deterministic orchestration — patient
  resolution, insurance siteKey derivation, CDT code mapping
- Custom CDT aliases stored per-user in DB (TwilioSettings JSON blob)
  with GET/PUT /api/ai/cdt-aliases endpoints
- Chatbot UI: new steps for eligibility-id-ready, check-and-claim-ready,
  and need-insurance-clarification with insurance picker
- Settings UI: CDT Aliases CRUD table with built-in alias reference

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Gitead
2026-06-03 17:44:19 -04:00
co-authored by Claude Sonnet 4.6
parent 4274cd61dc
commit ba2882957a
8 changed files with 2357 additions and 133 deletions
@@ -137,6 +137,27 @@ export const twilioStorage = {
});
},
async getCdtAliases(userId: number): Promise<{ phrase: string; cdtCode: string }[]> {
const settings = await db.twilioSettings.findUnique({ where: { userId } });
const all = (settings?.templates as Record<string, any>) || {};
const raw = all["_cdt_aliases"];
if (!Array.isArray(raw)) return [];
return raw.filter(
(r: any) => typeof r?.phrase === "string" && typeof r?.cdtCode === "string"
);
},
async saveCdtAliases(userId: number, aliases: { phrase: string; cdtCode: string }[]): Promise<void> {
const settings = await db.twilioSettings.findUnique({ where: { userId } });
const existing = (settings?.templates as Record<string, any>) || {};
const updated = { ...existing, "_cdt_aliases": aliases };
await db.twilioSettings.upsert({
where: { userId },
update: { templates: updated },
create: { userId, accountSid: "", authToken: "", phoneNumber: "", templates: updated },
});
},
async getRecentCommunicationsByUser(userId: number, limit = 20) {
return db.communication.findMany({
where: { patient: { userId } },