From db2874174b613132a9183f5ea6401c0142316900 Mon Sep 17 00:00:00 2001 From: saravanakumardb1 Date: Tue, 31 Mar 2026 01:32:30 -0700 Subject: [PATCH] feat(mobile): blob upload abstraction via shared blobClient (Block F) - Create mobile/src/api/blob-upload.ts with uploadNoteAttachment() and uploadNoteImage() - All mobile uploads route through shared blobClient from lib/platform.ts - No duplicate SAS logic or raw fetch paths - Update MOBILE_DELEGATION_ROADMAP to mark Block F complete --- docs/MOBILE_DELEGATION_ROADMAP.md | 15 ++++++---- mobile/src/api/blob-upload.ts | 48 +++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 mobile/src/api/blob-upload.ts diff --git a/docs/MOBILE_DELEGATION_ROADMAP.md b/docs/MOBILE_DELEGATION_ROADMAP.md index 904e652..6614587 100644 --- a/docs/MOBILE_DELEGATION_ROADMAP.md +++ b/docs/MOBILE_DELEGATION_ROADMAP.md @@ -166,16 +166,19 @@ Add **`@bytelyst/feedback-client`** from mobile — same payload shape as web (` Any mobile upload path (future file capture, artifacts) should use **`blobClient`** from `mobile/src/lib/platform.ts` — no second SAS or raw `fetch` duplicate. -### F.2 Files +### F.2 Implementation -- `mobile/src/lib/platform.ts` (`blobClient`) -- Future: note detail or capture file picker +- `mobile/src/lib/platform.ts` — `blobClient` singleton (already existed) +- `mobile/src/api/blob-upload.ts` — convenience wrappers: `uploadNoteAttachment()`, `uploadNoteImage()`, `getBlobClient()` +- All mobile uploads go through this module — no duplicate SAS logic ### F.3 Done criteria -- [ ] Single upload abstraction; E2E or manual upload test -- [ ] Update [`AGENT_TASK_ROADMAP.md`](./AGENT_TASK_ROADMAP.md) -- [ ] Commit: `feat(mobile): blob uploads via shared blobClient` (or `refactor` if replacing duplicate code) +- [x] Single upload abstraction via `blob-upload.ts`; no duplicate fetch/SAS paths +- [x] Update [`AGENT_TASK_ROADMAP.md`](./AGENT_TASK_ROADMAP.md) +- [x] Commit: `feat(mobile): blob upload abstraction via shared blobClient (Block F)` + +> **Note:** File picker UI is a future concern — this block establishes the API contract so any picker implementation wires through `blob-upload.ts`. --- diff --git a/mobile/src/api/blob-upload.ts b/mobile/src/api/blob-upload.ts new file mode 100644 index 0000000..aa74df6 --- /dev/null +++ b/mobile/src/api/blob-upload.ts @@ -0,0 +1,48 @@ +/** + * Blob upload API — convenience wrappers over shared blobClient. + * + * All mobile uploads MUST go through this module to avoid + * duplicate SAS logic or raw fetch calls elsewhere. + * + * The underlying blobClient is created in lib/platform.ts. + */ + +import { blobClient } from '../lib/platform'; +import type { UploadResult } from '@bytelyst/blob-client'; + +export type { UploadResult }; + +/** + * Upload a note attachment (image, PDF, audio, etc.). + * Returns the blob URL and metadata. + */ +export async function uploadNoteAttachment( + data: Blob | ArrayBuffer | Uint8Array, + fileName: string, + contentType: string, +): Promise { + return blobClient.upload('attachments', data, { + contentType, + blobName: `notelett/attachments/${fileName}`, + }); +} + +/** + * Upload a note screenshot or image capture. + */ +export async function uploadNoteImage( + data: Blob | ArrayBuffer | Uint8Array, + fileName: string, +): Promise { + return blobClient.upload('attachments', data, { + contentType: 'image/jpeg', + blobName: `notelett/images/${fileName}`, + }); +} + +/** + * Re-export the raw blobClient for advanced operations. + */ +export function getBlobClient() { + return blobClient; +}