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
(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]
@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]