Skip to content

Requirements

System-level functional and non-functional requirements for the Item Image Upload feature. Each requirement is derived from the source use cases and feature specifications, and is verifiable by an independent agent once the system is built.

  • Source use cases: GEN::MEDIA::0001 (Set), GEN::MEDIA::0002 (Remove), GEN::MEDIA::0003 (View), REF::ITM::0003::0010 (Create), REF::ITM::0004::0006 (Edit)
  • Feature specs: GEN::MEDIA::FR-0001FR-0020, REF::ITM::FR-0006FR-0008
  • Design decisions: TD-01 through TD-08, Decision Log
  • Scoping: Scoping

IDRequirementSource
FR-001The SPA shall provide a single image input surface that accepts file selection, drag-and-drop, clipboard paste, URL text entry, data URI text, and camera capture without requiring the user to select an input mode.GEN::MEDIA::FR-0001, 0001::0001.UC
FR-002The SPA shall automatically detect the input method and route the provided image through the appropriate internal processing path. All paths converge to the managed upload path — no input method results in a directly persisted external URL.GEN::MEDIA::FR-0002, 0001::0002.FS, TD-01
FR-003When the user provides an HTTPS URL, the SPA shall validate the URL, attempt to fetch the image directly, and on CORS failure fall back to the BFF for reachability check and/or image fetch.0001::0004.FS, TD-02
FR-004For HTTPS URL inputs, the SPA shall fetch the image, render it in the image editor for crop/zoom/rotate, and upload the result via the managed presigned-upload path. The external URL shall never be persisted as the entity image reference.GEN::MEDIA::FR-0020, TD-01, TD-05
FR-005When clipboard content is HTML with an embedded image URL, the SPA shall extract the URL, validate it, fetch the image SPA-side, and route it through the managed upload path.0001::0002.FS, TD-01, SD-14
FR-006When clipboard content is a raw image blob, the SPA shall generate a local preview and route the binary content through the managed upload path on confirm.0001::0002.FS
FR-007When the user provides data: or blob: URI text, the SPA shall decode the content as image data and route it through the managed upload path. These URI schemes shall never be persisted.GEN::MEDIA::FR-0012, GEN::MEDIA::FR-0013
IDRequirementSource
FR-008The SPA shall accept images in JPEG, PNG, WebP, HEIC, and HEIF formats. SVG shall be rejected.GEN::MEDIA::FR-0005, 0001::0003.FS
FR-009The SPA shall enforce a maximum file size per entity type (default 10 MB). When the file exceeds the limit, the SPA shall attempt auto-compression (85% JPEG quality, max 2048px longest edge) before rejecting.GEN::MEDIA::FR-0006, 0001::0003.FS, SD-10
FR-010The SPA shall accept only HTTPS URLs as external image references. All other URI schemes (http:, data:, blob:, javascript:, file:) shall be rejected for URL input.GEN::MEDIA::FR-0009, 0001::0004.FS
FR-011The SPA shall verify URL reachability and confirm the response content type is a supported image format before accepting a URL input. On CORS failure, the BFF shall proxy the reachability check.GEN::MEDIA::FR-0010, 0001::0004.FS, TD-02
FR-012The Backend shall validate that all persisted image URLs match the expected CDN host and key pattern. URLs not matching the managed storage pattern shall be rejected.GEN::MEDIA::FR-0011, TD-05
FR-013All validation error messages shall use plain language understandable by non-technical users and suggest a corrective action.GEN::MEDIA::FR-0008
IDRequirementSource
FR-014The SPA shall render an image preview at the target aspect ratio defined by the entity type (1:1 square for Items).GEN::MEDIA::FR-0014, 0001::0005.FS, SD-06
FR-015The SPA shall provide crop, zoom, rotate, pan, and reset operations in the image preview editor. The crop aspect ratio is locked per entity type and is not user-modifiable.GEN::MEDIA::FR-0015, 0001::0005.FS, SD-12
FR-016When replacing an existing image, the SPA shall display the current image alongside the new preview for visual comparison (side-by-side on desktop, tabbed on mobile). Replacing an image uses the same interaction flow as setting one for the first time (the comparison layout is the only difference).GEN::MEDIA::FR-0004, GEN::MEDIA::FR-0016, 0001::0005.FS, SD-11
FR-017The SPA shall display a preview of the provided image before the user confirms, regardless of input method.GEN::MEDIA::FR-0003
IDRequirementSource
FR-018The SPA shall display copyright acknowledgment text inline in the confirm dialog footer. The text states that by providing images, the user accepts they have the right to use them. The confirm button is always enabled; no blocking checkbox or gate is required.0001::0006.FS, SD-07, FD-18
FR-019Server-side logging of the copyright acknowledgment is out of scope. The acknowledgment is SPA-only — no backend record of acknowledgment is required.TD-04
IDRequirementSource
FR-020The Backend (Operations) shall generate presigned POST credentials for uploading images to managed storage. The BFF shall proxy this request, adding authentication headers and tenant context.TD-03, TD-08
FR-021The SPA shall upload image file bytes directly to Storage using the presigned POST credentials. The BFF and Backend are not in the data path for file bytes.TD-06, GEN::MEDIA::FR-0019
FR-022After a successful upload, the SPA shall persist the resulting CDN URL on the entity via the BFF/Backend API.0001::0006.FS
FR-023The Backend shall verify the uploaded object exists in Storage (via HEAD request) before persisting the image URL on the entity.Prior design: Static Asset Repository write flow step 5
FR-024Presigned POST credentials shall enforce Content-Type (must start with image/) and Content-Length (1 byte to max file size) via S3 policy conditions.TD-08, prior research on content validation
IDRequirementSource
FR-025The SPA shall require user confirmation before removing an entity’s image. On confirm, the entity’s image reference is cleared via the BFF/Backend API.GEN::MEDIA::FR-0017, 0002::0001.UC
FR-026Removing an image shall clear the entity’s image URL field. The entity shall display a default placeholder.GEN::MEDIA::FR-0017, REF::ITM::FR-0006
FR-027Previous image references shall be retained in the entity’s version history. Managed assets shall not be deleted on removal or replacement.GEN::MEDIA::FR-0018
IDRequirementSource
FR-028The SPA shall render entity images as thumbnails in grid views, scaled to fit cell dimensions while preserving aspect ratio. Entities without images shall show a default placeholder (initials or generic icon).0003::0001.UC, REF::ITM::FR-0007
FR-029Hovering over an image thumbnail in the grid for ~500 ms shall show a popover with a larger preview. The popover shall dismiss on mouse-out. No action icons are shown in the hover popover — quick inspection only. Single click on the cell selects the row (AG Grid default).0003::0002.FS, CD-08 (revised)
FR-030When an image URL is unreachable or returns an error, the grid cell shall show the default placeholder with an error badge. No toast or error message shall be displayed. The hover preview popover shall not be shown for error-state thumbnails.0003::0003.FS
FR-031While an image is loading, the grid cell shall show a lightweight loading indicator (shimmer or spinner).0003::0003.FS
IDRequirementSource
FR-032Double-click or Enter on an image cell in a grid view shall open a modal overlay containing the full image editor (same unified input surface as the form context).0001::0007.FS, SD-15
FR-033On confirm in the grid editor, the change shall be persisted and the grid row shall reflect the updated thumbnail. On discard, no change.0001::0007.FS
IDRequirementSource
FR-034The Add Item form shall include an optional image field that uses the unified image input surface. Items saved without an image shall display a default placeholder.REF::ITM::0003::0010.UC, REF::ITM::FR-0006
FR-035The Edit Item form shall allow changing or removing the item’s image. Changing follows the set-image flow (FR-001–FR-024). Removing follows the remove flow (FR-025–FR-027).REF::ITM::0004::0006.UC, REF::ITM::FR-0008
IDRequirementSource
FR-036The BFF shall issue CloudFront signed cookies scoped to the active tenant’s key prefix (/<tenantId>/*) on session establishment. CloudFront shall reject image requests that do not carry a valid signed cookie.TD-11
FR-037Signed cookies shall have a short TTL (default 30 minutes, configurable). The SPA shall proactively refresh cookies before expiry (at approximately 50% of TTL).TD-12
FR-038When the active tenant changes during a session (without re-authentication), the SPA shall immediately request new signed cookies from the BFF scoped to the new tenant. Until the new cookies arrive, image requests to the new tenant’s images may return 403; the SPA shall show loading state during the refresh window. On 403 from a CDN image request, the SPA shall refresh cookies and retry (max 1 retry per image request); if the retry also returns 403, show error-state placeholder.TD-12, Audit #13
FR-039The BFF signed-cookie endpoint shall validate the caller’s session and extract the tenant ID from the authenticated context. It shall not accept a tenant ID as a client-supplied parameter.TD-11
IDRequirementSource
FR-040The SPA shall enforce a minimum image dimension of 200x200 pixels. Images below this threshold shall be rejected with a plain-language error. Per-entity-type configurability of minimum dimensions is deferred to a future release; V1 uses this hardcoded default.GEN::MEDIA::FR-0007, Audit #6
IDRequirementSource
FR-041Only one image upload may be active per browser session. While an upload is in the Uploading state, other image upload triggers (form fields, grid cell editors) shall be disabled.Audit #20
FR-042The image editor shall always produce JPEG output regardless of input format. HEIC/HEIF inputs are converted to JPEG during editing. The contentType in the presigned credential request shall be image/jpeg.Audit #21

IDRequirementSource
NFR-001Image uploads via presigned POST shall complete within 10 seconds for files up to 10 MB on a typical broadband connection (10 Mbps upload).Derived from UX responsiveness expectations
NFR-002CDN-served images shall load within 500 ms for cached content (P95) in the US/EU delivery region.Derived from grid rendering performance
NFR-003Presigned POST credential generation (Backend round-trip) shall complete within 1 second (P95).Derived from upload UX flow responsiveness
NFR-004Grid thumbnail rendering shall not cause visible reflow or layout shifts when images load asynchronously.0003::0003.FS
IDRequirementSource
NFR-005All persisted image URLs shall originate from managed storage. The Backend shall reject any image URL that does not match the expected CDN host and key pattern.TD-05, GEN::MEDIA::FR-0011
NFR-006Presigned POST credentials shall be scoped to a specific S3 key prefix (tenant-partitioned) and shall expire within 15 minutes (aligned with existing uploadSignatureDuration).Derived from TD-03, tenant isolation
NFR-007S3 object keys shall include the tenant ID as a path prefix for tenant isolation.Derived from existing architecture, DQ-3
NFR-008The BFF URL reachability check shall only target external URLs. It shall never check URLs on managed storage (those are known-good).TD-02
NFR-009The BFF URL reachability endpoint shall implement request-rate limiting and target-URL validation to prevent SSRF abuse.Derived from OWASP SSRF prevention
NFR-017Product images shall be treated as sensitive data. CDN access shall require valid CloudFront signed cookies. Unauthenticated requests to the CDN shall receive 403 Forbidden.TD-11
NFR-018CloudFront signed cookies shall be scoped to the requesting tenant’s key prefix. A cookie issued for Tenant A shall not grant access to Tenant B’s images.TD-11
NFR-019Signed cookie TTL shall default to 30 minutes (configurable). Shorter TTLs reduce the breach window if cookies are exfiltrated.TD-12
NFR-020The CloudFront signing key pair shall be rotatable without downtime. CloudFront trusted key groups support multiple active keys for zero-downtime rotation.TD-11, operational security
IDRequirementSource
NFR-010If an upload fails mid-transfer, the SPA shall allow the user to retry without re-entering the image. The presigned POST credentials shall be re-requested if expired.Derived from upload UX robustness
NFR-011Incomplete multipart uploads in S3 shall be automatically aborted via lifecycle rule (1-day expiration).Derived from prior research on upload failure handling
NFR-012Orphaned uploads (presigned credentials used but entity never updated) remain in the persistent bucket indefinitely. At projected volumes (~50 GB, ~$1.10/month), storage cost is negligible. A periodic cleanup mechanism (scan job comparing S3 objects against entity image URLs) is deferred to a future enhancement. No staging prefix is used — uploads go directly to the final key.Derived from DQ-5/DQ-8 prior research, R-002
IDRequirementSource
NFR-013The design shall support at least 100 tenants × 1,000 images per tenant (~50 GB total storage) without architectural changes.Derived from prior cost projection
NFR-014Image delivery shall use CloudFront CDN to avoid backend involvement in the read path.TD-06, TD-07
IDRequirementSource
NFR-015The image upload capability shall be generic (parameterized by ImageFieldConfig) so that future entity types can adopt it without re-implementing the upload workflow.GEN::MEDIA cross-cutting design principle
NFR-016AWS-specific implementation details shall be isolated in the AWS actor specification. Scenario diagrams shall reference “Storage” as a black box.TD-07
IDRequirementSource
NFR-021The SPA shall display an upload progress indicator (percentage or indeterminate) during the Uploading state. For presigned POST uploads, the XHR/fetch progress event provides byte-level tracking.R-006 mitigation, Audit #18

The following requirements are documented for future implementation. They are out of scope for V1 (see Scoping).

IDRequirementSource
NFR-022The image editor controls (crop, zoom, rotate, pan, reset) shall be operable via keyboard. Focus order shall follow the visual layout.WCAG 2.1 AA, Audit #19
NFR-023The ImageUploadDialog modal overlay shall implement a focus trap. Focus returns to the triggering element on close.WCAG 2.1 AA, Audit #19
NFR-024Image thumbnails in the grid shall include alt text derived from the entity name (e.g., “Product image for [Item Name]”). Placeholders shall have alt="" (decorative).WCAG 2.1 AA, Audit #19
NFR-025Upload state transitions (uploading, success, error) shall be announced to screen readers via ARIA live regions.WCAG 2.1 AA, Audit #19

The User actor is a human operating through a modern web browser. The system design assumes the following behaviors and constraints:

IDAssumptionImplication
UA-001The user operates a modern desktop or mobile browser supporting <canvas>, FileReader, Clipboard API, and fetch.Client-side image processing (crop, rotate, compression) is feasible. HEIC/HEIF support depends on browser capabilities — the SPA should detect and gracefully degrade.
UA-002The user may be non-technical (e.g., shop floor worker, inventory manager).All error messages must be plain-language. Technical jargon (MIME type, presigned URL, Content-Length) must never be exposed.
UA-003The user may paste images from diverse sources (screenshot tools, Google Image Search, Amazon product pages, email clients).Clipboard handling must detect multiple content types (image blob, HTML with embedded URL, plain text URL, unrecognized).
UA-004The user may provide images from external URLs that are CORS-restricted.The BFF must provide a reachability/fetch fallback for CORS-blocked URLs.
UA-005The user operates within an authenticated session. The active tenant may change during the session without re-authentication (multi-tenant users).Tenant isolation is enforced at every layer. The user cannot access or modify images belonging to a tenant they are not currently operating in. CDN signed cookies must be refreshed on tenant switch (FR-038).
UA-006Multiple users may edit the same entity concurrently.Last-writer-wins semantics apply. The bitemporal persistence layer provides a full audit trail. No locking or conflict resolution is required for image fields.
UA-007The user expects uploaded images to be immediately visible after confirmation.The upload workflow must be synchronous from the user’s perspective — no background processing delay between confirm and display. CDN propagation must be near-instant (or the initial read uses S3 directly).

Copyright: (c) Arda Systems 2025-2026, All rights reserved