---
stepsCompleted: ['step-01-init', 'step-02-discovery', 'step-02b-vision', 'step-02c-executive-summary', 'step-03-success', 'step-04-journeys', 'step-05-domain', 'step-06-innovation', 'step-07-project-type', 'step-08-scoping', 'step-09-functional', 'step-10-nonfunctional', 'step-11-polish']
inputDocuments: []
workflowType: 'prd'
date: '2026-04-27'
classification:
  projectType: 'iot_embedded + saas_multi_user'
  domain: 'general_consumer_family'
  complexity: 'medium'
  projectContext: 'greenfield'
---

# Product Requirements Document - pictureFrame

**Author:** Matt Edholm
**Date:** 2026-04-27

## Executive Summary

pictureFrame is a handcrafted e-ink digital picture frame ecosystem built to be given as a meaningful gift. The physical frame — custom-built around a Waveshare e-ink display driven by an ESP32 — is battery-powered or plugin at the recipient's choice. A companion web application manages image libraries, device configuration, family sharing, and the rotation cycle that keeps each frame alive over time. The frame displays one image per configured interval, cycling through a curated pool of approved photos drawn from family uploads, shared images, or linked photo collections. Setup requires only scanning two QR codes; ongoing use requires no interaction unless the recipient wants it.

Target users are gift recipients — family members who receive a frame — and the family network that contributes by uploading and sharing photos. A super-admin account manages the global image pool, device fleet, and system-level operations.

### What Makes This Special

Commercial digital frames are purchased. This one is built — by hand, with intent, for a specific person. The e-ink display is a deliberate aesthetic choice: it looks like something that belongs on a wall, not a screen. Battery power removes the constraint of proximity to an outlet. The software doesn't add friction — it quietly keeps the frame personal and current as the family adds to it over time. The differentiator is not a feature set. It is the act of making.

The technical decisions — server-side image processing, thin ESP32 client, per-device approval workflows, uniqueness-tracked rotation, email-based sharing with inline approve/disapprove — all serve a single goal: the frame should feel effortless to receive and effortless to live with.

## Success Criteria

### User Success

- The frame rotates images on the configured schedule without user intervention. A recipient who never opens the app is a fully successful user.
- A frame never displays a blank screen. The last successfully transferred image persists indefinitely through WiFi outages, sync failures, and power loss.
- First-time setup completes without technical assistance: scan AP QR → enter WiFi credentials → scan setup QR → log in → device linked.
- Status is communicated passively via border color. No notification, no app required to understand device state.

### Business Success

- Every gifted frame works reliably for a non-technical recipient from day one.
- The web app supports extended family participation without requiring it — participation is optional, not a success condition.
- System architecture keeps a monetization path open without building for it in V1.

### Technical Success

- Image transfers are atomic. A display refresh only occurs after a complete, confirmed transfer. A mid-transfer power loss leaves the previous image on screen.
- Server pre-renders all images per device display model and orientation at upload/approval time. The ESP32 never performs image transformation.
- Soft-delete and cron-based cleanup run without manual intervention. No orphaned assets accumulate.
- QR-based provisioning succeeds on first attempt on both iOS and Android.
- Yellow border (sync fail) and red border (no WiFi) render correctly and consistently.

### Measurable Outcomes

- Zero blank frames in normal operation
- Provisioning first-attempt success rate: ≥95% on standard home WiFi
- Image cycle runs on schedule ±5 minutes of configured interval
- Sync failure surfaced visually within one cycle period

## Product Scope

### V1 — Full Feature Set

Everything described in this document is V1. No phased rollout.

**Firmware (ESP32):**
- Two-phase provisioning: AP mode (WiFi credentials only) → STA mode (account setup via web app QR)
- Timer-based image pull from server
- Atomic image write (display only refreshes after confirmed transfer)
- Per-device orientation (landscape/portrait)
- Border status indicators: yellow (sync fail), red (no WiFi)
- 5-second button hold to reset and re-provision
- Deep sleep between pull cycles

**Web Application:**
- Open registration (email + password)
- Device registry: naming, orientation, rotation frequency, uniqueness window
- Image upload and library management (Uploaded / Shared filter)
- Per-device image approval workflow
- Collections support (approve all images in a collection)
- Email sharing with inline approve/disapprove (tokenized links, client-agnostic)
- Global pre-loaded image pool (admin-managed, available to all devices)
- Admin panel: fleet management, delete request queue, force hard delete, device audit log

**Server:**
- Image cycle engine: uniqueness tracking (window capped at available image count), rotation scheduling
- Pre-rendering pipeline: display-ready 4bpp assets generated per device model and orientation at upload/approval time
- Soft-delete + cron-based hard-delete (cleans when no approvals remain)
- Device ownership transfer: atomic purge and relink on re-provisioning to new account
- MAC-authenticated image endpoint

### Post-MVP

- Apple Photos and Google Photos collection integration (link album → all images auto-approved)
- Additional Waveshare display sizes as hardware is defined
- Monetization layer (subscription tiers — architecture supports it, not built in V1)

### Vision

- Multiple display form factors and custom frame hardware kits
- Broader family social features
- Potential commercial distribution of frames as a product

## User Journeys

### Journey 1: Margaret — The Recipient *(Primary User, Happy Path)*

Margaret is 74. She lives alone in Fort Wayne. Her kids worry she spends too much time looking at the same four photos on her refrigerator. One Christmas morning she unwraps a wooden frame — heavier than she expected. There's a small card: *"Scan the QR code to connect to WiFi."*

She holds her phone up to the QR code on the screen. Her camera app asks if she wants to join "PictureFrame-A3F2." She taps yes. A simple page opens asking for her home WiFi password. She types it in and taps Connect. The display updates — a new QR appears with the message "Connected — scan to finish setup." She scans it. A web page opens. She logs in with the email her son set up for her. The frame reboots. Twenty seconds later, a photo of her grandchildren at a lake house fills the screen. She doesn't touch it again for three months.

Six weeks in, the frame cycles to a photo she's never seen before — her daughter uploaded it from a birthday party. She didn't ask for it. She didn't approve it. It just appeared. She calls her daughter. That's the product working.

**Capabilities revealed:** Two-phase QR provisioning, captive portal WiFi entry, setup-page account login, timer-based rotation, family image sharing, passive recipient experience with zero ongoing interaction required.

---

### Journey 2: Matt — The Builder *(Gift Giver, Setup Path)*

Three weeks before Christmas, Matt flashes new firmware to an ESP32, wires it to the Waveshare display, and fits it into a custom walnut frame he's been working on. He scans the provisioning QR, joins the AP, enters the home WiFi credentials. The frame connects; the success screen shows a setup QR. He scans it, logs in as admin, and names the device *"Margaret's Frame."* He sets orientation to portrait, rotation to daily, uniqueness window to 30.

He uploads twelve photos from his phone — Thanksgiving, a lake trip, a grandkid's first birthday. He approves all twelve for Margaret's device from the web app. He pulls up the server logs, confirms the pre-rendered assets are ready. He powers the frame off, packs it in a box with a typed card explaining the QR code, and ships it.

On Christmas morning he gets a text: *"The frame is beautiful."* He opens the admin panel and confirms the device is online.

**Capabilities revealed:** Two-phase provisioning, super-admin device naming, orientation/frequency/uniqueness settings, image upload, per-device approval, server pre-rendering pipeline, admin monitoring.

---

### Journey 3: Sarah — The Contributor *(Family Member, Sharing Path)*

Sarah is Matt's sister. She gets an email in January: *"Matt has added you to the pictureFrame family."* She clicks the link, creates an account, and uploads three photos — her kids, a recent trip, a candid from the holidays.

She sees Margaret in the shared user list. She taps "Share to Margaret" on one photo. An email lands in Margaret's inbox: *"Sarah shared a photo with you."* The email shows the image and two buttons: **Approve** and **Decline.** Margaret taps Approve. A simple page opens — no login required — asking which frame to add the photo to. Margaret picks her living room frame and taps Done. The photo enters the approved pool for that device and will appear within the next cycle.

Sarah never needed to understand approvals, device settings, or the cycle engine. She just shared a photo.

**Capabilities revealed:** Family account creation, image upload, user-to-user sharing, email approve/decline flow, tokenized device-selection page, image entering approved pool for selected device(s).

---

### Journey 4: Margaret's Frame Goes Offline *(Primary User, Edge Case)*

February. Margaret's internet provider does a firmware update on her router at 3am. The frame tries its scheduled pull at 6am and can't reach the server. It draws a red border around the photo on screen and goes back to sleep.

Margaret notices it at breakfast. She calls her son. He's not home. She forgets about it.

Her router comes back online at noon. At the next scheduled pull the frame reaches the server, retrieves the next image, completes the atomic transfer, refreshes the display. The border disappears. Margaret notices it looks different. She doesn't know what changed.

**Capabilities revealed:** Red border on WiFi failure, silent retry on reconnect, last-image persistence, no user action required for recovery.

---

### Journey 5: Matt as Super Admin *(Admin Path)*

In March, Sarah decides she wants a photo permanently removed — an old picture she regrets uploading. She can soft-delete it from her library, but she wants it gone from the server entirely. She taps "Request hard delete" from the image detail page.

Matt gets a notification in the admin panel: *"Sarah has requested a hard delete for 1 image."* He reviews the image, confirms it's not approved on any device, and clicks force hard delete. The file is removed from storage. Sarah gets a confirmation email.

Later that week, a second frame gets physically reset by accident. A new family member completes provisioning and claims the device. The server atomically purges the previous image history and links the device to the new account. Matt sees the ownership transfer in the device audit log.

**Capabilities revealed:** User hard-delete request, admin delete request queue, force hard delete, device ownership transfer audit log.

---

### Journey Requirements Summary

| Journey | Capabilities Required |
|---|---|
| Margaret (recipient) | Two-phase QR provisioning, captive portal WiFi entry, timer pull, border indicators, passive rotation |
| Matt (gift giver) | Device naming, settings config, image upload, approval, pre-rendering, admin monitoring |
| Sarah (contributor) | Account creation, image upload, share to device, email approve/decline flow |
| Margaret offline (edge case) | WiFi failure detection, red border, silent retry, last-image persistence |
| Matt as admin | Hard-delete request queue, force delete, ownership transfer audit log |

## IoT/Embedded + SaaS Specific Requirements

### Hardware Requirements

- **Microcontroller:** ESP32 (esp32dev) — dual-core, 240MHz, 4MB flash, WiFi 802.11 b/g/n
- **Display:** Waveshare 7.3" 6-color e-ink (E-Ink Spectra 6), 800×480px, SPI interface — extensible to additional Waveshare models as device types
- **SPI pinout:** Per-hardware-variant firmware build constant. Current POC: SCK=18, MOSI=23, CS=5, DC=17, RST=16, BUSY=4. All-in-one ESP32+display boards (e.g. Waveshare ESP32 driver boards with ribbon cable) may define pins differently. Device type registry on the server tracks display model; firmware is built per hardware variant.
- **Power:** Battery or plugin at recipient's choice. E-ink retains image with zero power draw between refreshes.
- **Reset mechanism:** Physical button, 5-second hold triggers re-provisioning

### Connectivity & Provisioning

- **Normal operation:** WiFi STA mode, timer-based wake → pull → sleep cycle
- **Phase 1 (AP mode):** Device broadcasts provisioning AP. QR code on e-ink encodes AP SSID. Captive portal collects home WiFi SSID and password only — no server dependency, no account flow.
- **Phase 2a (success):** Device connects to home WiFi in STA mode. E-ink shows success message and a QR encoding `{APP_BASE_URL}/setup/{mac_address}` — a firmware build constant established after DNS is set up. User scans → web app → register or log in → device linked.
- **Phase 2b (failure):** E-ink fills red, AP re-activates, provisioning QR redisplays automatically. No user intervention required to retry.
- **Image transport:** HTTPS GET to server endpoint; pre-rendered binary asset returned
- **Status:** WiFi failure → red border. Sync failure (WiFi up, server unreachable) → yellow border. Both rendered locally without server involvement.

### Power Profile

- E-ink draws power only during refresh; image persists indefinitely with zero power.
- Deep sleep between pull cycles for battery efficiency.
- Rotation frequency configurable per device — longer intervals extend battery life significantly.
- No OTA in V1; API endpoint format is a stable contract by design.

### Device Identity & Security Model

- Each ESP32 is identified by its factory-burned MAC address.
- At provisioning, MAC→account mapping is stored server-side.
- Every image pull request includes the device MAC; server validates MAC is registered before serving.
- Re-provisioning to a new account atomically updates the MAC→account mapping and purges prior image history. Last-writer-wins — physical reset button is the authorization.
- HTTPS required for all device↔server communication.

### Multi-Tenancy & Permission Model

Each user account is an isolated tenant with its own image library and device registry. Devices are owned by exactly one account at a time. Shared images create a reference in the recipient's library, not a copy.

| Role | Capabilities |
|---|---|
| User | Own account, own devices, own images; share images; approve/decline shared images |
| Super admin | All user capabilities + cross-tenant device management, force hard delete, delete request queue, global image pool management |
| Device (ESP32) | Pull pre-rendered image for registered account via MAC-authenticated endpoint |

### Server-Side Rendering Pipeline

All image transformation occurs at upload/approval time, not at request time. Server stores pre-rendered assets per device model and orientation (landscape 800×480, portrait 480×800; additional sizes added as device types are defined). ESP32 receives a ready-to-display binary asset — no transformation on device. Format: 4bpp packed, Waveshare 6-color palette (BLACK=0x0, WHITE=0x1, YELLOW=0x2, RED=0x3, BLUE=0x5, GREEN=0x6).

### Implementation Constraints

- Phase 1 captive portal has no external dependencies — collects WiFi credentials only.
- APP_BASE_URL and API base URL are firmware build constants; DNS must be established before firmware development begins.
- API endpoint format must remain stable across firmware versions; breaking changes require a firmware version bump.
- Soft-delete + cron cleanup handles shared-image retention without manual intervention.
- Firmware builds are 1:1 with hardware configurations (device type), not 1:1 with individual devices.

## Project Classification

| | |
|---|---|
| **Project Type** | IoT/Embedded + Multi-user SaaS |
| **Domain** | General / Consumer / Family |
| **Complexity** | Medium |
| **Project Context** | Greenfield |

## Project Scoping

### Strategy

**Approach:** Experience MVP — value is the act of making and giving, not a tracked metric. V1 ships everything. Solo developer; single VPS; no phased rollout, no feature flags, no paid tier.

**Build Order:** Web application and DNS are prerequisites. App domain and API base URL are established first, then baked into firmware as build constants. No OTA in V1 — a stable API contract is the update strategy.

### Risk Mitigation

| Risk | Mitigation |
|---|---|
| **Provisioning UX failure** | Two-phase e-ink flow uses QR at every state. Phase 1 requires no server. Phase 2 failure renders full red screen and re-activates AP automatically. Physical reset always returns to Phase 1. |
| **Server load / pre-rendering latency** | Pre-render is synchronous at upload time. No device ever waits for rendering at pull time. |
| **Blank frame** | Last image persists through power loss and outages. Yellow/red border signals state. Recovery is automatic on reconnect. |
| **Orphaned assets** | Soft-delete + cron cleanup runs without intervention. Shared images retained until last approval is removed. Super-admin force-delete handles user requests. |
| **Device ownership dispute** | Last-writer-wins on physical reset. Physical access to the reset button is the authorization model. First claim cannot block a subsequent physical reset. |

## Functional Requirements

### User & Account Management

- FR1: Visitors can register a new account with an email address and password
- FR2: Registered users can log in to their account
- FR3: Super admin can view, edit, and delete any user account, device, or image across the system

### Device Management

- FR4: Users can register a device to their account via the provisioning setup flow
- FR5: Users can assign a name to each of their devices
- FR6: Users can configure display orientation (landscape or portrait) per device
- FR7: Users can configure the image rotation frequency per device
- FR8: Users can configure the uniqueness window (number of cycles before an image can repeat) per device
- FR9: When a device is re-provisioned to a new account, the system atomically purges the prior image history and transfers ownership
- FR10: Super admin can view, rename, reconfigure, and transfer any device across all accounts

### Image Library

- FR11: Users can upload photos to their personal image library
- FR12: Users can view their library filtered by source: Uploaded vs. Shared
- FR13: Users can soft-delete images from their library
- FR14: When an image is shared to a user, it appears in their library as a reference (not a copy)
- FR15: Super admin can add images to and remove images from a global pre-loaded image pool available to all devices

### Image Approval & Sharing

- FR16: Users can approve or decline images for a specific device in their account
- FR17: Users can share an image from their library to another user
- FR18: When an image is shared, the recipient receives an email containing the image and an approve action; clicking approve opens a device-selection page (no login required) where the recipient chooses which device(s) to add the image to, including an All Devices option
- FR19: The approval link works from any email client without requiring account creation or login
- FR20: Approved images enter the active rotation pool for the selected device(s)
- FR21: Users can approve all images within a collection for a device in a single action
- FR22: Users can request a full hard delete of their own image, which enters a super-admin review queue
- FR23: System sends confirmation to the user when their hard-delete request is fulfilled

### Device Provisioning

- FR24: Device enters provisioning mode when the reset button is held for 5 seconds
- FR25: In provisioning mode, device displays a scannable QR code for joining the provisioning access point
- FR26: User can enter home WiFi credentials through a captive portal served by the device
- FR27: On successful WiFi connection, device displays a QR code linking to the account setup page for that specific device
- FR28: On failed WiFi connection, device displays a failure indicator, reactivates the AP, and redisplays the provisioning QR code for retry
- FR29: Users can register a new account or log in to an existing account from the device setup page to link the device

### Image Rotation & Cycle Engine

- FR30: System automatically advances to the next approved image on the configured schedule for each device
- FR31: System tracks image display history per device to enforce the configured uniqueness window
- FR32: When the uniqueness window exceeds the count of available approved images, the window is treated as equal to the available image count
- FR33: System pre-renders images to display-ready format per device model and orientation at the time of upload or approval
- FR34: Device pulls its next pre-rendered image from the server on each scheduled cycle

### Display & Status

- FR35: Device displays the current image persistently with no power draw between refresh cycles
- FR36: Device retains and displays the last successfully transferred image through power loss and WiFi outages
- FR37: Device only updates the display after a complete, confirmed image transfer
- FR38: Device renders a yellow border when WiFi is connected but the server sync fails
- FR39: Device renders a red border when WiFi connectivity is unavailable

### Admin & Moderation

- FR40: Super admin can view a queue of user-submitted hard-delete requests and fulfill or dismiss them
- FR41: Super admin can force an immediate hard delete of any image in the system
- FR42: Super admin can view a device ownership transfer audit log
- FR43: System automatically hard-deletes soft-deleted images that have no remaining approvals via a scheduled background process
- FR44: Soft-deleted images with at least one active approval are retained until all approvals are removed

## Non-Functional Requirements

### Performance

- Image pre-rendering completes within 10 seconds of upload or approval trigger
- Device image pull endpoint returns the pre-rendered binary asset within 10 seconds on typical home broadband
- Web application pages load within 3 seconds on a standard broadband connection
- Image rotation fires within ±5 minutes of the configured interval

### Security

- All device-to-server communication occurs over HTTPS
- Device image pull requests are authenticated by MAC address; the server rejects requests from unregistered MACs
- Email inline approve/decline actions use single-use authorization links that expire after use or after a configurable TTL
- User accounts are isolated — a user cannot access another user's images or devices without an explicit sharing action
- Super admin access is restricted to a single designated account
- Device ownership transfer requires physical access to the reset button; remote re-provisioning is not possible

### Reliability

- A device must never display a blank screen in normal operation — the last successfully transferred image persists indefinitely through outages and power loss
- A display refresh only occurs after a complete, confirmed transfer; a mid-transfer interruption leaves the previous image on screen
- Soft-delete and scheduled cleanup run on a scheduled basis without manual intervention
- Breaking API changes are prohibited in V1. Any change to the API contract requires physical reflash of all deployed devices and is treated as a last resort.

### Accessibility

- All primary user journeys complete successfully on iOS Safari (latest) and Android Chrome (latest)
- Email sharing flows must work without requiring app installation or login on the recipient's device
