@primocaredentgroup/recalls-component
v0.7.1
Published
Convex component for clinic recalls, call center queue, action flows and capacity planning
Readme
Componente Recalls / Callcenter
Componente Convex riutilizzabile per la gestione operativa dei richiami clinici. Tutta la logica vive nel backend; il frontend example/ serve solo a validare il funzionamento prima dell'integrazione in PrimoUPCore.
Obiettivo
Trasformare la lista infinita di richiami in un motore operativo che:
- Legge i pazienti/casi candidati dal componente
campaigns - Genera task di richiamo prioritizzati (scoring operativo)
- Assegna un task alla volta agli operatori
- Registra sessioni, tentativi, esiti e tempi
- Permette supervisione realtime
- Collega ogni esito a un action flow configurabile (no hardcode per campagna)
- Supporta un builder di action flow estendibile
Architettura
convex/
├── convex.config.ts # App che monta il componente recalls
├── schema.ts # Schema minimale app
├── recallsApi.ts # Wrapper che espone le funzioni del componente
├── components/
│ └── recalls/
│ ├── convex.config.ts
│ ├── schema.ts # Schema completo del componente
│ ├── domain/ # Types e domain logic
│ ├── ports/ # Adapter verso campaigns (mock per MVP)
│ ├── services/ # Scoring, Queue, Session, ActionFlow, etc.
│ ├── queries.ts
│ ├── mutations.ts
│ ├── mutationsInternal.ts
│ ├── actions.ts
│ └── ...
example/ # Frontend minimale React + ViteConfine con Campaigns
| Campaigns (marketing) | Recalls (operativo) | |---------------------------|-------------------------| | Chi è contattabile | Quando entra in coda | | Perché contattabile | Score operativo | | Priorità marketing | Chi lo lavora | | Membership paziente-campagna | Tentativi, sessioni, esiti | | | Action flow post-esito |
Integrazione pull-based tramite adapter. Implementazione mock per MVP.
Schema entità
| Tabella | Descrizione |
|---------|-------------|
| callTasks | Task di richiamo con status, score, assignment |
| callAttempts | Tentativi di chiamata (esito, durata) |
| operatorSessions | Sessioni lavoro operatore |
| clinicRecallProfiles | Target giornalieri per clinica |
| actionFlowTemplates | Template per campaign key |
| actionFlowOutcomes | Outcomes per template |
| actionFlowSteps | Step per outcome |
| actionFlowExecutions | Esecuzioni runtime |
| actionFlowStepExecutions | Stato step-by-step |
| appointmentStubs | Intent appuntamento (per integrazione futura) |
| taskEvents | Audit log |
Flussi principali
- Avvio sessione → operatore seleziona clinica, avvia sessione
- Claim task → sistema assegna il prossimo task in base a score
- Avvio chiamata → crea attempt, task → in_progress
- Submit outcome → operatore seleziona esito, parte action flow
- Step execution → per step che richiedono input (collect_note, create_appointment_stub, schedule_retry)
- Completamento → task completed, session aggiornata
Come avviare
Prerequisiti
- Node.js 18+
- Account Convex (gratuito per dev)
1. Configurazione Convex
cd /Users/simone/Componente\ richiami
npx convex devAlla prima esecuzione verrà chiesto di creare/collegare un progetto Convex. Seguire il wizard.
2. (Opzionale) Seed dati demo
Solo per test locali. In produzione le campagne arrivano dal componente Campaigns:
npx convex run recallsApi:seedDemoDataCrea: 3 cliniche, 3 action flow template, ~5 task mock. Non necessario se usi l’integrazione Campaigns.
3. Frontend example
# Crea .env locale con l'URL Convex
cp example/.env.example example/.env
# Modifica example/.env con VITE_CONVEX_URL dal dashboard Convex
cd example
npm install
npm run devApri http://localhost:5174
- Operatore: seleziona clinica, opzionalmente campagna, operatore; avvia sessione; prendi task; avvia chiamata; seleziona esito; completa step
- Admin: missione, task, sessioni
- Templates: lista action flow template
API principali
Query
getClinicMission- missione giornaliera clinicagetOperatorCurrentSession- sessione attiva operatoregetNextTaskPreview- prossimo task disponibile (supporta filtrocampaignId)getCampaignsForClinic- campagne con task attivi per una clinicagetTaskDetail- dettaglio tasklistTasks- task per clinicalistSessions- sessionigetActionFlowTemplate- template per campaigngetSupervisionOverview- dashboard
Mutations
startOperatorSession/endOperatorSessionclaimNextTaskstartCallAttemptsubmitOutcomesubmitActionFlowStepcompleteActionFlowExecutionpauseTask
Actions
seedDemoData
Come caricare campagne sulla clinica
Le campagne non arrivano dal seed: arrivano dal componente Campaigns.
- Nel componente Campaigns: crea una campagna, assegnala alla clinica X
- Build Audience: esegui "Build Audience" per costruire il target
- Sync: l’action
buildAudienceSnapshot(in PrimoUpCore) crea i task recalls per ogni paziente con telefono - Vista Operatore: seleziona clinica X → le campagne con task appaiono nel dropdown → filtra per campagna Y
L’host deve passare campaignId e campaignName in createTaskFromMembership quando crea i task da membership, così il frontend può mostrare il nome campagna e filtrare.
Uso come componente in PrimoUPCore
1. Copia il backend Convex
Copia in Primoupcore:
convex/components/recalls/(tutto il componente)convex/recallsApi.ts- Aggiorna
convex/convex.config.tsconapp.use(recalls, { name: "recalls" })
2. Importa i componenti React
import {
RecallsOperatorView,
RecallsAdminView,
RecallsConfigView,
RecallsTemplatesView,
} from "./components/recalls"; // o dal path dove li hai copiati
import { api } from "./convex/_generated/api";3. Usa i componenti
// Vista Operatore (call center)
<RecallsOperatorView
api={api.recallsApi}
clinicId={user.clinicId}
operatorId={user.id}
clinics={clinicsFromBackend}
operators={operatorsFromBackend}
showSeedButton={false}
/>
// Vista Admin/Supervisione
<RecallsAdminView
api={api.recallsApi}
clinicId={selectedClinicId}
clinics={clinics}
/>
// Configurazione target cliniche
<RecallsConfigView api={api.recallsApi} clinics={clinics} />
// Lista templates
<RecallsTemplatesView api={api.recallsApi} />I componenti richiedono ConvexProvider nel tree (già presente in app Convex).
Le props clinics e operators vanno popolate da Primoupcore (cliniche reali, utenti con ruolo operatore).
4. Struttura example per riferimento
example/src/components/recalls/
├── index.ts
├── types.ts
├── RecallsOperatorView.tsx
├── RecallsAdminView.tsx
├── RecallsConfigView.tsx
└── RecallsTemplatesView.tsxTODO integrazione PrimoUPCore
- Campaigns adapter (pull): il mock resta per demo; in produzione i task arrivano da
createTaskFromMembership+buildAudienceSnapshot(push da PrimoUpCore). - Auth: già gestito nel wrapper
recallsApi(permessicampaign.*);operatorId/clinicIddalla UI. - Appointment stubs: bridge PrimoUpCore (
recallsActionRegistry) sucreate_appointmente affini. - update_membership_status: dopo lo step, PrimoUpCore schedula
ingestRecallCallOutcome→campaigns.ingestCallOutcome(sync snapshot/membership). - Permissions: affinare ruoli operator/supervisor se servono permessi più granulari oltre
campaign.execute/campaign.create. - Twilio (test): action
twilioRecalls:sendRecallSmsin PrimoUpCore + envTWILIO_*.
Step types supportati
| Step | Descrizione |
|------|-------------|
| collect_note | Raccoglie nota dall'operatore |
| schedule_retry | Pianifica retry (ore configurabili) |
| update_membership_status | Aggiorna status membership (da collegare a campaigns) |
| close_task | Chiude il task |
| pause_task | Mette in pausa |
| create_followup_task | Crea task di followup |
| create_appointment_stub | Crea intent appuntamento |
| flag_contact_issue | Segnala problema contatto |
License
Uso interno PrimoUPCore.
