Skip to content

Notes: persist editor images to blob storage instead of inline base64 #86

Description

@shreekardittakavi

Spec: SDR 3.1.2 — "The editor shall support image uploading for diagrams, tables, and other visual learning content." Doc tech stack: "Would need a way to store images (maybe with Vercel blob). Suggestion: Cloudflare R2 + embeddings."

Current state

note-editor.tsx:240 falls back to uploadImageToDataUrl(file) when no uploadImage handler is passed:

const resolvedFile = uploadImage
  ? await uploadImage(file)
  : await uploadImageToDataUrl(file);

So images are base64-inlined into note.content jsonb. Consequences:

  • Row size balloons — a handful of screenshots can push a note into megabytes
  • Every note load transfers the full image payload, with no caching or CDN
  • Base64 inflates bytes by ~33% on top of that
  • No thumbnailing, no resizing, no dedupe

This degrades quietly as usage grows and works directly against SDR 4.3 (scalability) and 4.2 (performance).

Scope

  • Pick a blob store (Vercel Blob is the lowest-friction given Vercel deployment; Cloudflare R2 is cheaper at volume and is what the tech-stack doc suggests) and wire an authenticated upload route.
  • Store { url, width, height, size } in the block, not bytes.
  • Enforce mime allowlist and size cap server-side; scope objects per user.
  • Generate a resized display variant; keep the original.
  • Lifecycle: deleting a note should not orphan its blobs forever — decide on a cleanup path.
  • Migration for existing notes with inlined data URLs, or an explicit decision to leave them as-is.

Acceptance criteria

  • Editor image uploads go to blob storage and the note stores a URL
  • note.content size stays flat as images are added
  • Uploads are authenticated and user-scoped
  • Existing notes with data URLs still render

Metadata

Metadata

Assignees

No one assigned

    Labels

    BackendAPI, DB, and server-side workNote TakingCurrently, Taskmaster is split into two teams. this is one of themenhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions