Pages Blazor

Sitemap & cas d'usage

Routes principales et diagrammes de séquence pour les flows clés (conversation avec un agent, meeting live, génération de rapport).

Sitemap

graph LR Root["/"]:::auth --> Home["Home"] Root --> Auth["Auth
(login Identity)"]:::open Home --> Convs["/conversations"] Convs --> ConvNew["/conversations/new"] Convs --> ConvRoom["/conversations/{id}"] Home --> Meets["/meetings"] Meets --> MeetNew["/meetings/new"] Meets --> MeetRoom["/meetings/{id}"] Home --> Reports["/reports"] Reports --> RepDetail["/reports/{id}"] Reports --> RepFile["/reports/file"] Home --> Pipeline["/pipeline"] Home --> AccList["/accounts"] Home --> Prospects["/prospects"] Prospects --> ProspectDet["/prospects/{id}"] Home --> Camps["/campaigns"] Camps --> CampNew["/campaigns/new"] Home --> Approvals["/approvals"] Home --> Admin{Admin}:::admin Admin --> AdmAgents["/admin/agents"] Admin --> AdmUsers["/admin/users"] Admin --> AdmImport["/admin/import-prospects"] Admin --> AdmEnrich["/admin/enrichment"] classDef auth fill:#E0F2FE,stroke:#0EA5E9 classDef admin fill:#FEE2E2,stroke:#EF4444 classDef open fill:#F1F5F9,stroke:#64748B

Toutes les pages sont en [Authorize] sauf /Account/* (login). Les pages /admin/* exigent le rôle admin.

Cas d'usage 1 — Envoyer un message à un agent

Flow le plus utilisé. Démarre d'une page /conversations/{id}.

sequenceDiagram autonumber actor User participant Razor as ConversationRoom.razor participant Hub as ConversationHub participant Svc as ConversationService participant Mgr as ConversationRunnerManager participant Runner as ClaudeCliRunner participant DB as elynav.db User->>Razor: tape un message + Send Razor->>Hub: SendAsync(convId, text) Hub->>Svc: AppendUserMessageAsync(...) Svc->>DB: INSERT conversation_messages (Role=User, TurnIndex=N) Hub->>Mgr: GetOrCreateAsync(convId, agent) Mgr->>Runner: SendUserMessageAsync(text) Runner->>Runner: stream events loop Streaming Runner-->>Hub: TextDeltaEvent Hub-->>Razor: messageDelta (SignalR) Razor->>User: rendu progressif end Runner-->>Hub: AgentTurnEndedEvent Hub->>Svc: AppendAgentMessageAsync(content final) Svc->>DB: INSERT conversation_messages (Role=Agent) Hub-->>Razor: turnEnded

Cas d'usage 2 — Activation automatique d'un meeting

Un meeting créé avec ScheduledAt dans le futur est passé en Live par un HostedService.

sequenceDiagram autonumber participant Cron as MeetingActivationHostedService participant DB as elynav.db participant Hub as MeetingHub participant Razor as MeetingsList.razor loop Toutes les 30s Cron->>DB: SELECT meetings WHERE Status='Scheduled' AND ScheduledAt <= now DB-->>Cron: due meetings alt Au moins 1 meeting due Cron->>DB: UPDATE meetings SET Status='Live' Cron->>Hub: NotifyMeetingActivated(meetingId) Hub-->>Razor: meetingLive (SignalR push) Razor->>Razor: re-rendu avec badge "LIVE" end end

Cas d'usage 3 — Rapport quotidien à 20h

Cron Cronos 0 0 20 * * * qui génère un rapport markdown par agent actif.

sequenceDiagram autonumber participant Cron as DailyReportHostedService participant Reg as AgentRegistry participant Svc as ReportService participant Runner as ClaudeCliRunner (transient) participant DB as elynav.db Cron->>Reg: All agents loop Pour chaque agent actif Cron->>Svc: GenerateForAgentAsync(agent) Svc->>DB: INSERT agent_daily_reports (Status=Pending) Svc->>Runner: spawn + prompt "Génère ton rapport du jour" Runner-->>Svc: stream complet (text) Svc->>DB: UPDATE agent_daily_reports (ContentMd, Status=Ready) Svc->>Runner: StopAsync() end

Hiérarchie composants — Conversation Room

graph TD Layout[MainLayout.razor] Layout --> Nav[NavMenu.razor] Layout --> Body[Body Slot] Body --> Page[ConversationRoom.razor
@page /conversations/id] Page --> Header[Page Header
title + agents] Page --> Timeline[Messages Timeline] Timeline --> Msg[MessageBubble
x N] Page --> Composer[Composer
textarea + send] Page --> Sidebar[Agent Sidebar
active/inactive toggles] Page -.SignalR.-> Hub[/hubs/conversation]