Couches & dépendances
Architecture en couches classique .NET avec un projet dédié à l'intégration CLI externe.
Stack technique
Vue couches
MeetingHub, ConversationHub] Program[Program.cs
DI + middleware] end subgraph Core["ElynavCommand.Core — Business"] MeetingSvc[MeetingService] ConvSvc[ConversationService] ReportSvc[ReportService] RunnerMgr[ConversationRunnerManager] TurnMgr[TurnManager] HostedSvcs[HostedServices
MeetingActivation, DailyReport, RoleSeeder] Brevo[BrevoClient + EventProcessor] Sourcing[ProspectCsvImporter] end subgraph Bridge["ElynavCommand.AgentBridge"] Runner[ClaudeCliRunner] Registry[AgentRegistry] Events[AgentEvent records] end subgraph Data["ElynavCommand.Data — Persistence"] Ctx[ApplicationDbContext] AppEnt[App entities
Meeting, Conversation, AgentDailyReport] CrmEnt[CRM entities
Account, Contact, Opportunity, ...] Ident[Identity
ApplicationUser] end Pages --> MeetingSvc Pages --> ConvSvc Pages --> ReportSvc Pages --> Registry Hubs --> RunnerMgr Hubs --> TurnMgr MeetingSvc --> Ctx ConvSvc --> Ctx ReportSvc --> Ctx RunnerMgr --> Runner TurnMgr --> Runner HostedSvcs --> Ctx HostedSvcs --> Runner Brevo --> Ctx Ctx --> AppEnt Ctx --> CrmEnt Ctx --> Ident
Services principaux — diagramme de classes
Rôle de chaque projet
ElynavCommand.Web
Host Blazor Server. Configure DI, middleware ASP.NET, Identity, hubs SignalR (/hubs/meeting, /hubs/conversation), endpoint webhook Brevo, et l'ensemble des Pages Razor.
Program.cs, Components/Pages/*, Hubs/*ElynavCommand.Core
Toute la logique métier réutilisable. Services CRUD (Meeting, Conversation, Report), HostedServices pour les tâches background (MeetingActivationHostedService qui passe Scheduled → Live à l'heure dite, DailyReportHostedService au cron 20h, RoleSeederHostedService au boot), intégration Brevo, sourcing CSV.
Meetings/, Conversations/, Reports/, Brevo/, Sourcing/, Identity/, Tooling/ElynavCommand.Data
EF Core 10 sur SQLite. ApplicationDbContext unique qui mappe tables Identity (AspNet*, owned by EF migrations), tables App (meetings, conversations, agent_daily_reports, owned by EF migrations), et tables CRM existantes (accounts, contacts, etc., excluded from migrations — schéma géré par Salesforce/crm/schema.sql).
App/ (entities App), Crm/ (entities CRM), Identity/, Migrations/ElynavCommand.AgentBridge
ClaudeCliRunner spawn le binaire claude en sous-processus avec --print --output-format stream-json --input-format stream-json, écrit les messages user en JSON sur stdin, lit les events JSON sur stdout, parse en AgentEvent typés (TextDelta, ToolUse, ToolResult, AgentStarted, TurnEnded, Error). AgentRegistry expose la liste des agents lue depuis appsettings.json.
ClaudeCliRunner.cs, Agents/IAgentRegistry.cs, Agents/ElynavOptions.cs, AgentEvent.csCycle de vie d'un service injecté (DI)
| Service | Lifetime | Raison |
|---|---|---|
| IAgentRegistry | Singleton | Conf statique lue au boot |
| IClaudeCliRunnerFactory | Singleton | Factory stateless, instancie des Runners scoped |
| ITurnManager | Singleton | État partagé des meetings live entre clients SignalR |
| IConversationRunnerManager | Singleton | Cache de runners actifs par (convId, agent) |
| IMeetingService / IConversationService / IReportService | Scoped | Liés au DbContext scoped d'EF Core |
| ApplicationDbContext | Scoped | Standard EF Core (per-request) |
| EmailTemplateService | Singleton | Templates Markdig stateless |