Component: SaveFlow.tsx → useSaveFlow.ts
1. Client collects metadata (subject, sender, recipients, attachments list)
2. Client calls POST /api/office/save with:
- contentType: 'Email'
- triggerAiProcessing: true (default from DEFAULT_PROCESSING_OPTIONS)
- aiOptions: { profileSummary: true, ragIndex: true, deepAnalysis: false }
Component: OfficeEndpoints.cs → OfficeService.SaveAsync()
1. Creates ProcessingJob record in Dataverse
2. Retrieves email body + attachments via Microsoft Graph (OBO token)
3. Converts to .eml format using IEmailToEmlConverter
4. Uploads .eml to SharePoint Embedded via SpeFileStore
5. Creates Document record in Dataverse (via IDataverseService.CreateDocumentAsync)
6. Updates Document with SPE pointers, email metadata
7. Queues OfficeJobMessage to "office-upload-finalization" queue
8. Returns 202 Accepted with jobId
Status: Job marked as COMPLETE immediately (Option B flow) Issues:
- Creates Document record BEFORE worker runs
- Job status = Complete but workers haven't run yet
Component: UploadFinalizationWorker.cs
1. Receives message from "office-upload-finalization" queue
2. Checks if file already in SPE (TempFileLocation starts with "spe://")
3. Uses existing DocumentId from payload (created in step 2)
4. Creates EmailArtifact record
5. Extracts + uploads attachments as child Documents
6. IF payload.TriggerAiProcessing:
- Queues message to "office-profile" queue
ELSE:
- Marks job Complete
Issues Observed:
- Failing with "Incorrect attribute value type System.Int32" when updating ProcessingJob
- Dead-lettering messages → profile queue never receives them
Component: ProfileSummaryWorker.cs
1. Receives message from "office-profile" queue
2. Calls IAppOnlyAnalysisService.AnalyzeDocumentAsync()
3. Creates Analysis record with Document Profile playbook
4. IF payload.RagIndex:
- Queues to "office-indexing" queue
ELSE:
- Marks job Complete
Status: NEVER RUNS because UploadFinalizationWorker fails
Entry Points:
- POST /api/ai/analyze - Direct analysis endpoint
- Service Bus -
document-eventsqueue with topic subscription - Background Workers - ServiceBusJobProcessor listening to queue
Existing Components:
IAnalysisOrchestrationService- Orchestrates analysis pipelineIAppOnlyAnalysisService- App-only document analysisIAiToolService- AI tool execution frameworkIFileIndexingService- RAG indexing pipeline
Existing Flow:
Document Created
↓
Message to document-events queue
↓
ServiceBusJobProcessor picks up
↓
ProfileSummaryJobHandler processes
↓
Calls IAppOnlyAnalysisService.AnalyzeDocumentAsync()
↓
Creates Analysis record with playbook
↓
Queues indexing job if needed
We created NEW workers (UploadFinalizationWorker, ProfileSummaryWorker) that duplicate existing infrastructure:
- Existing:
ServiceBusJobProcessor+ProfileSummaryJobHandler - New (Office):
ProfileSummaryWorker
Result: Two separate pipelines doing the same thing
OfficeService marks job as COMPLETE immediately after upload, but workers haven't run yet.
Should: Job stays Running until ProfileSummaryWorker completes
The Office flow creates its own queue (office-profile) instead of using:
- Existing
document-eventsqueue - Existing
ProfileSummaryJobHandler
UpdateProcessingJobAsync has attribute type mismatches causing worker failures
User Saves Email in Outlook
↓
POST /api/office/save
├─ Upload .eml to SPE
├─ Create Document record
├─ Create EmailArtifact record
└─ Publish to EXISTING document-events queue <-- USE EXISTING
↓
EXISTING ServiceBusJobProcessor picks up
↓
EXISTING ProfileSummaryJobHandler processes
↓
EXISTING IAppOnlyAnalysisService creates Analysis
↓
EXISTING IFileIndexingService indexes if requested
Changes Required:
- Remove
ProfileSummaryWorker(duplicate) - Keep
UploadFinalizationWorkerfor Office-specific tasks (EmailArtifact, attachments) - UploadFinalizationWorker publishes to
document-eventsqueue instead ofoffice-profile - Let existing AI infrastructure handle analysis
Keep office-profile queue and ProfileSummaryWorker
BUT: ProfileSummaryWorker just calls existing IAppOnlyAnalysisService
Changes Required:
- Fix type mismatch bug in UpdateProcessingJobAsync
- Ensure ProfileSummaryWorker properly calls existing IAppOnlyAnalysisService
- Fix job status flow (don't mark Complete until workers finish)
Use Option A - eliminate duplication and use existing proven AI infrastructure.
Why:
- Existing
ProfileSummaryJobHandleralready does what we need - Existing
document-eventsqueue already exists - Less code to maintain
- Single pipeline = easier debugging
- AI enhancements benefit all document sources (not just Office)
Implementation:
- UploadFinalizationWorker should publish to
document-eventsinstead ofoffice-profile - Remove
ProfileSummaryWorker.cs - Remove
office-profilequeue from Service Bus - Existing
ServiceBusJobProcessor+ProfileSummaryJobHandlerhandles analysis