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
| Table | Purpose |
|---|---|
msintegrationv2.users | Mailbox user identity and application metadata |
msintegrationv2.mailboxes | Internal UUID, provider identity, credentials, sync state, archive policy |
msintegrationv2.users_folders | Folder tree and parent relationships |
msintegrationv2.folder_delta_tokens | Encrypted opaque folder checkpoint and health |
msintegrationv2.message_delta_tokens | Encrypted per-folder message checkpoint and health |
msintegrationv2.sync_cycles | Webhook, periodic, and recovery cycles |
msintegrationv2.sync_fetch_batches | Read-only fetch batches and final delta candidates |
msintegrationv2.sync_stage_items | Sanitized body-free items for idempotent apply |
msintegrationv2.newMails | Message metadata, body/raw keys, attachment state and details |
msintegrationv2.conversations | Normalized Graph conversation identity |
msintegrationv2.categories_link | Authoritative conversation category relationships |
msintegrationv2.attachments | Attachment metadata and object key |
msintegrationv2.mailbox_item_exports | Export state, retries, failure class, and object key |
kafka.sync_operations | Acceptance, execution, and confirmation state |
kafka.mailbox_execution_state | Per-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.