Skip to content

Requirements: Backend Services for Item Image Upload

Author: Claude Code for jmpicnic | Date: 2026-03-31 | Status: Draft

Requirements: Backend Services for Item Image Upload

Section titled “Requirements: Backend Services for Item Image Upload”

Functional and non-functional requirements for the backend implementation of image upload. These requirements derive from the backend specification (BE-FR/BE-NFR), the goal, and the analysis.


IDRequirementSource
REQ-BE-001The system shall generate presigned POST forms for uploading images to S3. The POST policy document shall include conditions enforcing: key (exact match), Content-Type (starts-with image/), content-length-range (1 byte to max file size), x-amz-meta-tenant-id (exact match), x-amz-meta-author (exact match), x-amz-meta-arda-key (exact match), and x-amz-server-side-encryption (AES256). Signature duration: 15 minutes (configurable).BE-FR-001, TD-08, TD-16
REQ-BE-002The system shall construct S3 object keys in the format <tenantId>/images/<uuid>.<ext>. The UUID shall be generated server-side using a cryptographically secure random source. The extension shall be derived from the requested content type: image/jpegjpg, image/pngpng, image/webpwebp, image/heicheic, image/heifheif.BE-FR-002, TD-16
REQ-BE-003The system shall construct CDN URLs from object keys in the format https://<cdn-host>/<tenantId>/images/<uuid>.<ext>, where <cdn-host> is the configured CDN domain.BE-FR-007, TD-16
REQ-BE-004The presigned credential endpoint shall return the S3 upload URL, all form fields required for POST submission, the object key, and the CDN URL in a single response.BE-FR-007
REQ-BE-005The presigned credential endpoint shall construct the Arda-Key metadata value in the format operations/item/imageUrl/<uuid>.<ext>.BE-FR-001, TD-16
REQ-BE-006Each call to the presigned credential endpoint shall generate a new UUID and a new set of credentials. The endpoint shall be idempotent in the sense that multiple calls produce independent, valid credential sets.BE-NFR-003
IDRequirementSource
REQ-BE-007Before persisting a non-null imageUrl on an entity, the system shall validate that the URL matches the expected CDN host and key pattern. URLs that do not match shall be rejected with a 400 response. This validation is subject to the grandfathering rule (REQ-BE-011, TD-15): validation is skipped when the imageUrl is unchanged from the persisted value.BE-FR-003, TD-05, TD-15
REQ-BE-008Before persisting a non-null imageUrl, the system shall validate that the URL’s key prefix matches the requesting tenant’s ID. Cross-tenant URLs shall be rejected.BE-FR-003
REQ-BE-009Before persisting a non-null imageUrl, the system shall perform a HeadObject request to S3 to verify the uploaded object exists and that x-amz-meta-tenant-id matches the requesting tenant.BE-FR-004
REQ-BE-010The system shall accept null as a valid imageUrl value to clear an entity’s image.BE-FR-005
REQ-BE-011When the imageUrl value in an update request is unchanged from the currently persisted value, the system shall skip CDN pattern validation and HEAD verification (grandfathering).TD-15
REQ-BE-012Previous image references shall be retained in the entity’s bitemporal version history. The system shall not delete S3 objects on image replacement or removal.BE-FR-006
IDRequirementSource
REQ-BE-013The system shall expose POST /v1/item/<itemEId>/image-upload-url as the presigned credential endpoint, scoped under the item resource path.TD-13
REQ-BE-014The presigned credential endpoint shall accept a JSON body with contentType (string, required) and contentLength (integer, required).BE-FR-001
REQ-BE-015The presigned credential endpoint shall require the same authentication as other item endpoints: API key + tenant headers (X-Tenant-Id, X-Author, X-Request-ID).BE-FR-001
REQ-BE-016The presigned credential endpoint shall return 400 for invalid content types (not starting with image/) or missing required fields.BE-FR-001
IDRequirementSource
REQ-BE-017The operations CloudFormation shall import image infrastructure exports: ImageAssetBucketArn, ImageAssetBucketName, ImagePresignRoleArn, ImageCdnDomain.Goal deliverable #10
REQ-BE-018The operations IAM role shall have s3:GetObject and s3:PutObject on the image asset bucket and sts:AssumeRole on the image presigning role. IAM policies are scoped at the bucket level (${BucketArn}/*), not per-tenant prefix. Tenant isolation is enforced at the application level: presigned POST policy conditions bake in the tenant ID (server-signed, client cannot alter), and post-upload HEAD verification validates x-amz-meta-tenant-id matches the requesting tenant from ApplicationContext (TD-20). CDN tenant isolation is enforced via CloudFront signed cookies scoped to /<tenantId>/* (TD-11).BE-NFR-002, TD-11, TD-20
REQ-BE-019Image infrastructure values shall be wired through Helm to application configuration, following the existing uploadBucketArn pattern.Goal deliverable #11
IDRequirementSource
REQ-BE-020Common S3 capabilities (presigned PUT, presigned POST, HEAD verification, metadata validation) shall be consolidated in S3AssetService. CsvS3BucketDirectAccess shall delegate all S3 primitives to S3AssetService (TD-17, TD-18).Goal, Analysis 3.x, TD-17, TD-18
REQ-BE-021After refactoring, CsvS3BucketDirectAccess shall retain all CSV-specific behavior (GET with decompression, row/batch flow parsing) while delegating S3 primitives to S3AssetService.Goal constraint #6, TD-18
REQ-BE-022All existing CsvS3DirectAccessTest and S3BucketAccessTest tests shall continue to pass without modification after refactoring.Goal constraint #6

IDRequirementSource
REQ-BE-NFR-001Presigned POST credential generation shall complete within 1 second (P95).BE-NFR-001
REQ-BE-NFR-002Each new class shall have passing unit tests before any dependent class is started. New code shall achieve a minimum of 80% line and branch coverage.Goal constraint #8
REQ-BE-NFR-003Code coverage shall meet or exceed targets configured in Gradle build scripts for both repositories.Goal SC #14
REQ-BE-NFR-004Both common-module and operations shall build successfully (make clean build) at each phase gate.Goal SC #5, #12

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