Skip to main content

Microsoft onboarding storage reference

Microsoft onboarding uses PostgreSQL, S3-compatible object storage, and a search projection. Complete Graph setup and storage configuration first.

Owner identity​

providerMailboxUserId is the Microsoft Graph user ID resolved at MailboxIdentityResolved. Email addresses can change, so they do not define these object paths. Better Auth userId and emailAccountId identify application ownership and onboarding routing. They are not the provider object-prefix owner.

Object keys​

users/{providerMailboxUserId}/emails/{emailId}/body.html
users/{providerMailboxUserId}/emails/{emailId}/raw.fts
users/{providerMailboxUserId}/emails/{emailId}/attachments/{emailId}_|_{filename}

For example, a message owned by GRAPH_USER_ID can use:

users/GRAPH_USER_ID/emails/MESSAGE_ID/body.html
users/GRAPH_USER_ID/emails/MESSAGE_ID/raw.fts
users/GRAPH_USER_ID/emails/MESSAGE_ID/attachments/MESSAGE_ID_|_invoice.pdf

The layout sanitizes path segments. Bucket selection comes from configuration. Database rows store object keys, not bucket URLs.

Bodies​

The worker uploads HTML while reading metadata. body_s3_key records the key. For this path, the SQL message body stays empty. Detail reads prefer that stored key. Legacy email-bodies/ objects remain a compatibility fallback.

Raw FastTransfer data​

Graph exportItems returns raw FastTransfer data. The worker decodes and processes it, then stores the original bytes as raw.fts. msintegrationv2.newMails.raw_fts_s3_key points to the object. msintegrationv2.mailbox_item_exports records export state.

Attachments​

The worker extracts files from the decoded FastTransfer stream. It uploads their bytes. msintegrationv2.attachments stores message identity and filename. It also stores available content type/content ID, size, SHA-256 metadata, and object key. It does not store the file bytes in that metadata row.

Tables​

TablePurpose
msintegrationv2.usersMailbox user identity and application metadata
msintegrationv2.mailboxesInternal UUID, provider identity, credentials, sync state, archive policy
msintegrationv2.users_foldersFolder tree and parent relationships
msintegrationv2.folder_delta_tokensEncrypted opaque folder checkpoint and health
msintegrationv2.message_delta_tokensEncrypted per-folder message checkpoint and health
msintegrationv2.sync_cyclesWebhook, periodic, and recovery cycles
msintegrationv2.sync_fetch_batchesRead-only fetch batches and final delta candidates
msintegrationv2.sync_stage_itemsSanitized body-free items for idempotent apply
msintegrationv2.newMailsMessage metadata, body/raw keys, attachment state and details
msintegrationv2.conversationsNormalized Graph conversation identity
msintegrationv2.categories_linkAuthoritative conversation category relationships
msintegrationv2.attachmentsAttachment metadata and object key
msintegrationv2.mailbox_item_exportsExport state, retries, failure class, and object key
kafka.sync_operationsAcceptance, execution, and confirmation state
kafka.mailbox_execution_statePer-mailbox order and exclusive executor lease

Incremental synchronization​

The TypeScript backend handles later metadata and body changes with the same body-key layout. IndependentQueProcessor performs read-only Graph fetches and S3 staging. QueProcessor applies changes under the mailbox lease and finalizes checkpoints. Raw FastTransfer export and attachment extraction belong to onboarding or full recovery.

Development cleanup boundary​

The explicit development S3 eraser covers both email-bodies/ and users/. This removes old and current development objects. It is destructive maintenance, not an import prerequisite or normal recovery. Use recovery guidance first.