Entity Media Behaviors
Use cases and scenarios for the GEN::MEDIA (Entity Media) area. These behaviors define the cross-cutting contract for attaching, replacing, and removing media assets — primarily images — on any main entity that supports a media field. Any main entity that carries an image or file reference (for example, Item.imageUrl) inherits these behaviors. Entity-specific deviations or extensions must be documented in the entity’s own domain area.
The design principle is one flow, automatic detection: the user has a single interaction surface for providing an image, regardless of whether they pick a file, drag-and-drop, paste from clipboard, or type a URL. The system classifies the input and routes it through the appropriate internal path (managed upload or external URL reference). This distinction is invisible to the user.
Infrastructure details — presigned URL workflows, CDN delivery, storage key structure, and tenant isolation — are defined in the Item Image Upload project and its FileStore design. This document specifies only the user-facing behavioral contract.
GEN::MEDIA::0001 — Set Entity Image
Section titled “GEN::MEDIA::0001 — Set Entity Image”The user sets, replaces, or updates the image for an entity. This single use case covers all input methods (file selection, drag-and-drop, clipboard paste, and URL entry) and both first-time and replacement scenarios. The system detects the input type and routes it through the appropriate internal path without requiring the user to choose a mode.
| Depends | GEN::ENT-DA::0003, GEN::ENT-DA::0004 |
| Status | New-distinct |
GEN::MEDIA::0001::0001.UC — Set Image via Unified Input Surface
Section titled “GEN::MEDIA::0001::0001.UC — Set Image via Unified Input Surface”The user activates the image area on an entity form — by clicking an empty image placeholder, clicking a “Change image” control on an existing image, or interacting with a dedicated image field. The system presents a unified input surface that accepts any supported input method. The user provides an image and sees a preview. On confirm, the image is saved and the entity display updates. On cancel, no change is made.
When input validation fails (unsupported format, file too large, unreachable URL), the system displays the error message inline within the image area. The image area remains active — the user can immediately provide a different image without dismissing the error or restarting the interaction. The error message clears automatically when new input is detected.
When an image already exists, the current image remains visible during the interaction. The new image replaces it only on confirm. The previous image is shown alongside the preview for visual comparison when the entity type supports it.
Postcondition: The entity’s image is set or updated. The new image is visible wherever the entity is displayed.
GEN::MEDIA::0001::0002.FS — Input Detection and Routing
Section titled “GEN::MEDIA::0001::0002.FS — Input Detection and Routing”The unified input surface accepts input and classifies it automatically. The user never selects a mode.
- File selection or drag-and-drop — The user picks a file from the OS file dialog or drags a file onto the input surface. The system reads the file locally and routes it through the managed upload path (presigned URL upload to storage, resulting in a CDN-backed URL).
- Clipboard paste — The user pastes content from the clipboard (Ctrl+V / Cmd+V). Clipboard behavior varies by source application:
- Image blob (most common — e.g., screenshot tools, image editors, macOS Finder, Windows Explorer): The browser provides raw image data. The system generates a local
data:orblob:URI for immediate preview rendering. On confirm, the binary content is extracted and routed through the managed upload path. Thedata:URI is transient and never persisted. - HTML with embedded image URL (e.g., Google Docs, Google Image Search, Amazon.com, Gmail, Outlook desktop): The clipboard contains HTML markup with an embedded image URL. The system extracts the image URL from the markup, validates it per
GEN::MEDIA::0001::0004, fetches the image SPA-side, and routes it through the managed upload path (same as URL text entry). - Unrecognized format (e.g., proprietary app data, plain text without URL pattern): The system shows the unrecognized-text error.
- Image blob (most common — e.g., screenshot tools, image editors, macOS Finder, Windows Explorer): The browser provides raw image data. The system generates a local
data:orblob:URI text — If the pasted or typed text begins withdata:orblob:, the system does not treat it as a URL reference. Instead, it attempts to decode the content as image data and route it through the managed upload path, identical to a clipboard paste. If decoding fails (malformed URI, unsupported format, or the content is not a valid image), the system shows the unrecognized-text error. These scheme prefixes are never stored as entity image references.- URL text entry — The user types or pastes text into the input surface. If the text matches an HTTPS URL pattern, the system validates the URL per
GEN::MEDIA::0001::0004. On successful validation, the SPA fetches the image from the URL, renders it in the editor for crop/zoom/rotate, and on confirm uploads the result via the managed upload path (presigned upload to storage, resulting in a CDN-backed URL). The external URL is never persisted directly. - Unrecognized text — If the pasted or typed text does not match a URL pattern and is not image data, the system shows an inline error: “This doesn’t look like an image or a link to one. Try uploading a file or pasting a web address.”
- Camera capture — On mobile devices, a dedicated “Take photo” affordance is presented alongside the file picker. The captured photo is routed through the managed upload path, identical to file selection. On desktop devices where a camera is available, the OS file dialog may include a camera option. The detailed mobile interaction design (tap targets, viewfinder framing, orientation handling) is defined in the entity type’s mobile UX specification.
GEN::MEDIA::0001::0003.FS — Accepted Formats and Size Limits
Section titled “GEN::MEDIA::0001::0003.FS — Accepted Formats and Size Limits”The following constraints apply uniformly regardless of input method:
- Accepted image formats: JPEG, PNG, WebP, HEIC/HEIF.
- Maximum file size: Defined per entity type; default 10 MB. If the file exceeds the maximum size, the system attempts to compress and resize it automatically (target: 85% JPEG quality, maximum 2048 pixels on the longest edge). If the result is still too large, the system shows the size error. When compression is applied, the system shows a brief inline message: “Your image has been optimized for best display quality.”
- Minimum dimensions: Defined per entity type where applicable.
HEIC/HEIF is the default photo format on modern iPhones and many Android devices. The system accepts these formats natively. SVG is not accepted — vector images are not appropriate for entity reference photos and pose security risks (embedded scripts).
On validation failure, the system shows a plain-language message. Examples:
- “This file is too large. The maximum size is 10 MB.” (never “Payload exceeds maxContentLength”)
- “This file type isn’t supported. Try a JPEG, PNG, WebP, or HEIC image.” (never “invalid MIME type image/bmp”)
- “This image is too small for a clear display. Try a larger image.”
GEN::MEDIA::0001::0004.FS — URL Scheme and Reachability Validation
Section titled “GEN::MEDIA::0001::0004.FS — URL Scheme and Reachability Validation”When the input is classified as a URL:
- Accepted schemes: HTTPS only. The system rejects
data:,blob:,javascript:,file:, and plainhttp:schemes at both client and server. - Rejection message: “Only secure web addresses (https) are accepted.”
- Reachability check: The system performs a HEAD request to verify the URL responds with an image content type. On failure: “We couldn’t load an image from this address. Check that the link points directly to an image.”
- Content-type sniff: The response must indicate an image content type (
image/jpeg,image/png,image/webp,image/heic,image/heif). If the content type does not match: “The link doesn’t point to a supported image type. Try a direct link to a JPEG, PNG, WebP, or HEIC image.” - Server-side defense in depth: The API rejects any image URL field value that does not match the HTTPS scheme, regardless of client-side validation.
GEN::MEDIA::0001::0005.FS — Preview and Crop
Section titled “GEN::MEDIA::0001::0005.FS — Preview and Crop”After the system accepts the input and before the user confirms:
- The image is rendered in a preview area at the target aspect ratio defined by the entity type.
- The crop aspect ratio is a design-time parameter defined per entity type and is not modifiable by the user at runtime. For example, Item product images use a fixed 1:1 (square) ratio. The user can reposition and scale the visible area within the locked aspect ratio.
- The preview works identically regardless of input method — the user sees no difference between a dragged file, a pasted clipboard image, and a validated URL.
- For URLs, the preview loads the remote image. If loading fails or is slow, a placeholder with a spinner is shown; if it times out, the system displays: “The image is taking too long to load. Try a different link or upload the image directly.”
Comparison layout (when replacing an existing image):
- Desktop: The existing image is shown in a small reference window alongside the new image in a larger preview viewport.
- Mobile / small viewports: Two tabs allow the user to flip between the existing and new image.
- No existing image: The comparison area is not shown; only the new image preview is displayed.
Drop zone affordances: In the empty state (before an image is provided), the input surface shows a dashed-border drop area with visual cues for drag-and-drop and paste, a URL text field, an “Upload from computer” button, and a “Dismiss” button to abandon the interaction. When a file is dragged over the drop zone, the border highlights.
Edit operations available in the preview:
- Crop — Reposition and scale the visible area within the entity-type aspect ratio.
- Zoom — Zoom in or out within the preview area.
- Rotate — Rotate the image in 90-degree increments.
- Pan — Reposition the image within the crop frame.
- Reset — Revert all edits and restore the original image.
- Remove background — Optional toggle that strips the image background and outputs a transparent PNG. The user sees the result in the preview before confirming. If the result is poor, the user can toggle it off to revert. Implementation may use client-side ML models or a server-side API.
Interaction states:
View— The entity form is displayed with the current image (or placeholder).EmptyImage— The user has activated the image area; no new image has been provided yet. The drop zone is shown.ProvidedImage— A new image has been provided and is shown in the preview. Available actions: accept, discard (returns to EmptyImage), edit (crop/pan/zoom/reset).FailedValidation— Input validation failed. Error message is displayed inline. The user can retry immediately (returns to EmptyImage) or dismiss the interaction.Warn— The user attempts to dismiss while a new image is staged. A confirmation prompt warns that the image will be discarded. The user can confirm (exits) or cancel (returns to ProvidedImage).
GEN::MEDIA::0001::0006.FS — Confirm and Persist
Section titled “GEN::MEDIA::0001::0006.FS — Confirm and Persist”Before the upload is accepted, the system presents a copyright acknowledgment. The user must provide an affirmative confirmation (mandatory checkbox or click) that they own or have a license to use the image and that uploading infringing material may result in account termination. This applies to all input methods. The acknowledgment is SPA-only in the current release; server-side logging of the acknowledgment is out of scope (TD-04) and deferred to a future enhancement if needed.
On confirm, the system persists the image reference on the entity:
- All input methods converge to the managed upload path. The final image (after crop/zoom/rotate) is uploaded to managed storage via the presigned upload workflow. The resulting CDN URL is stored on the entity’s image field. For HTTPS URL inputs, the SPA fetches the image, renders it in the editor, and uploads the result — the external URL is never persisted.
On cancel, any in-progress upload is aborted and no change is made to the entity.
When replacing an existing image:
- The previous image reference (whether managed or external) is retained in the entity’s version history per
GEN::ENT-DA::0008. Managed assets are not deleted; they remain accessible for historical display. Archival and purging of superseded assets is out of scope.
GEN::MEDIA::0001::0007.FS — Grid Inline Edit Entry Point
Section titled “GEN::MEDIA::0001::0007.FS — Grid Inline Edit Entry Point”When the user triggers inline edit on an image cell in a list/grid view (double-click or Enter on a selected cell), a modal overlay appears over the grid. The overlay contains the full image editor — the same unified input surface defined in GEN::MEDIA::0001::0001.UC, including all input methods, preview, crop, and comparison with the existing image.
On confirm, the change is persisted per GEN::MEDIA::0001::0006.FS, the overlay closes, and the grid row reflects the updated thumbnail. On discard, the overlay closes with no change to the entity.
The modal overlay prevents interaction with the background grid while active. The grid does not scroll or reflow while the overlay is open.
GEN::MEDIA::0002 — Remove Entity Image
Section titled “GEN::MEDIA::0002 — Remove Entity Image”The user removes the current image from an entity, reverting it to the default placeholder.
| Depends | GEN::ENT-DA::0004 |
| Status | New-distinct |
GEN::MEDIA::0002::0001.UC — Remove Image
Section titled “GEN::MEDIA::0002::0001.UC — Remove Image”The user triggers the remove action on an entity’s image — via a remove/clear control visible on the image area or within the entity edit form. A confirmation prompt appears: “Remove this image? The [entity type] will show a default placeholder instead.” On confirm, the image reference is cleared and the entity displays the default placeholder. On cancel, no change is made.
Postcondition: The entity’s image field is cleared. The entity displays a default placeholder wherever the image was previously shown.
Postcondition: The previous image reference (whether managed or external) is retained in the entity’s version history per GEN::ENT-DA::0008. Managed assets are not deleted on removal; they remain accessible for historical display. Archival and purging of disassociated assets is out of scope.
GEN::MEDIA::0003 — View Entity Image
Section titled “GEN::MEDIA::0003 — View Entity Image”The user views an entity’s image in a list/grid context — as a thumbnail in the grid and as a full-size image in an inspector overlay.
| Depends | GEN::LST::0001 |
| Status | New-distinct |
GEN::MEDIA::0003::0001.UC — View Image in Grid
Section titled “GEN::MEDIA::0003::0001.UC — View Image in Grid”The grid renders a thumbnail of the entity’s image in the image column. The thumbnail is scaled to fit the cell dimensions while preserving aspect ratio. If no image is set, a default placeholder is shown (initials derived from the entity name, or a generic icon).
Postcondition: The image is visible as a thumbnail in the grid row wherever the entity is displayed in a list view.
GEN::MEDIA::0003::0002.FS — Image Quick Inspection
Section titled “GEN::MEDIA::0003::0002.FS — Image Quick Inspection”Hovering over an image thumbnail in the grid for approximately 500 ms shows a popover with a larger preview of the image. The popover dismisses on mouse-out. This provides quick visual inspection without leaving the grid context or consuming the click gesture (which is reserved for row selection per AG Grid defaults).
The popover is not a modal — no focus trap, no overlay. It is not shown for error-state thumbnails (no URL to preview).
GEN::MEDIA::0003::0003.FS — Thumbnail Fallback and Error State
Section titled “GEN::MEDIA::0003::0003.FS — Thumbnail Fallback and Error State”When the image URL is unreachable, returns an error, or loading times out:
- The grid cell shows the default placeholder (same as the no-image state) with an error badge to distinguish it from a simple absence of an image. The error badge is a small visual indicator (e.g., a warning icon overlay on the placeholder).
- No error message or toast is displayed — the fallback is inline and silent.
- The hover preview popover is not shown for error-state thumbnails.
When the image is loading (slow network):
- The grid cell shows a lightweight loading indicator (e.g., a subtle shimmer or spinner within the cell). Once loaded, the thumbnail replaces the indicator without page reflow.
Cross-Cutting Concerns
Section titled “Cross-Cutting Concerns”Permissions
Section titled “Permissions”All authenticated users can set and remove entity images. Fine-grained role-based restrictions are not implemented in the current system and are deferred to a future permissions model.
Concurrency
Section titled “Concurrency”Last-user-wins semantics apply. The system does not lock the entity during image editing. If two users update the same entity’s image concurrently, the last write takes effect. The bitemporal persistence layer provides a full audit trail of who changed the image and when — see GEN::ENT-DA::0008.
Bulk CSV Semantics
Section titled “Bulk CSV Semantics”The system API uses PUT semantics for entity updates, meaning the full entity payload replaces the stored entity. An omitted or empty image field in a CSV import row clears the entity’s image (consistent with PUT semantics). PATCH semantics (partial updates that preserve unmentioned fields) are not in the current system.
Summary
Section titled “Summary”| Use Case | Scenarios | UC | FS |
|---|---|---|---|
GEN::MEDIA::0001 Set Entity Image | 7 | 1 | 6 |
GEN::MEDIA::0002 Remove Entity Image | 1 | 1 | 0 |
GEN::MEDIA::0003 View Entity Image | 3 | 1 | 2 |
| Total | 11 | 3 | 8 |
Copyright: © Arda Systems 2025-2026, All rights reserved