Goal: Frontend Implementation for Item Image Upload
Implement the frontend services that enable image upload, display, and management for the Item entity. This covers Phase 3 (BFF proxy routes and CDN cookie signing), Phase 4 (SPA component integration, grid display, upload orchestration, and form wiring), and the api-proxy type-safe client updates defined in the implementation phasing.
The frontend never generates presigned credentials or validates image URLs server-side — that is the Backend’s responsibility (TD-03, TD-05). The BFF acts as an authenticated proxy enriching requests with tenant context, and provides CORS fallback and CDN cookie signing. The SPA orchestrates the user interaction, direct-to-S3 upload, and CDN-based rendering.
Context
Section titled “Context”The Item Image Upload project has completed system design. The
SPA specification and
BFF specification define the frontend modules, interfaces, and state machines required.
AWS infrastructure (Phase 1) is
code-complete: S3 bucket, CloudFront CDN with OAC, IAM presigning role, and
signing key group are all provisioned. The
backend services (Phase 2) are in progress:
POST /v1/item/image-upload for presigned POST credential generation and
PUT /v1/item/item/<itemEId> with CDN URL validation.
The UX component library has been through two iterations. The original 19
image components were implemented in PR #63
(component specification). A
subsequent update (seb/inline-card-image-upload branch) introduced several
changes: the ImageDropZone was redesigned with a simplified layout
(InputGroup for URL entry, integrated HEIC conversion via maybeConvertHeic
utility, improved URL drag-and-drop with RFC 2483 parsing); the
ImageUploadDialog replaced the separate CopyrightAcknowledgment checkbox
with inline footer text (confirm is always enabled); and two new components
were added — ItemCardEditor (WYSIWYG card editor organism with inline image
upload) and ArdaConfirmDialog (lightweight confirm dialog atom). The
callback interfaces for backend integration (onUpload: (file: Blob) => Promise<string> and onCheckReachability: (url: string) => Promise<boolean>)
remain unchanged. Components are exported via the canary entry point and
consumed by arda-frontend-app as an npm dependency. This project may require
further updates to the components to support production backend integration
(real upload progress, error/retry states); the extent of those changes is a
design decision documented in
upload-component-backend-analysis.md.
The api-proxy package (@arda-cards/api-proxy) provides type-safe proxy
classes for every Arda REST API endpoint. The ItemProxy already supports
entity CRUD and CSV upload operations but is missing the image-upload-specific
method for POST /v1/item/image-upload.
The arda-frontend-app uses a BFF architecture: Next.js API routes
(/api/arda/...) proxy requests to the Backend with authentication and tenant
headers. The existing proxy pattern (JWT verification, UserContext extraction,
header injection) provides the template for the new image upload routes. The
Item forms (ItemFormPanel) already include imageUrl in the type system and
form state, with a disabled image dropzone placeholder. The app currently uses
Redux for client state and @tanstack/react-table for grid rendering; this
project introduces @tanstack/react-query as a platform investment for
server-state management — not just for image upload, but as the go-forward
pattern for all data fetching in the app (see
tanstack-adoption-exploration.md).
Architectural decisions made during project preparation (recorded in the decision log):
- FD-01: Design system components use typed data provider hooks (Option
C) for backend connectivity. Components never import
@tanstack/react-querydirectly; the app provides TanStack-backed implementations via props, factory functions, or context. See tanstack-component-binding-analysis.md. - Hierarchical edit lifecycle: Components manage local drafts via a
standardized
useDraft<T>hook, validate intrinsically, push confirmed results up via typed callbacks, and receive contextual errors from parents. See abstract-component-lifecycle.md. - AG Grid cell editors: Use factory functions (
createTypeaheadCellEditor,createImageCellEditor) that close over typed provider hooks. Column definitions are the assembly point where providers are wired. api-proxyis BFF-only at runtime: The SPA never imports@arda-cards/api-proxyruntime code; type-only re-exports are permitted (FD-13). It calls BFF routes via plainfetch(). The BFF usesItemProxyfromapi-proxyto call the Backend.
Repositories
Section titled “Repositories”api-proxy(Arda-cards/api-proxy) — type-safe Backend client: new image upload proxy method and response typesux-prototype(Arda-cards/ux-prototype) — design system package (@arda-cards/design-system). Image components are updated here to support production backend integration via typed data provider hooks (FD-01). This project also introduces the lifecycle framework types (ValidationResult,EditableComponentProps<T>,useDraft<T>) and validation function exports that establish the pattern for all future editable components. A new version is published to GitHub Packages. Components are exported via thecanaryentry point.arda-frontend-app(Arda-cards/arda-frontend-app) — BFF routes (Phase 3) and SPA integration (Phase 4): proxy endpoints, CDN cookie signing, TanStack Query hooks, grid integration, upload orchestration, and form wiring. Imports image components from@arda-cards/design-system/canary— components are not copied into this repository.documentation(Arda-cards/documentation) — project planning documents, specifications, session logs, and byproducts
In Scope
Section titled “In Scope”api-proxy — Backend Client Updates:
- Image upload proxy method on
ItemProxy— new methodcreateImageUploadUrl(request)that callsPOST /v1/item/image-uploadon the Backend. The endpoint is module-scoped (not entity-scoped — see api-proxy-update-to-operations-2.21.md for the path analysis). Request includescontentTypeandcontentLength. Response includesuploadUrl,formFields,objectKey, andcdnUrl. - Response types —
ImageUploadUrlRequestandImageUploadUrlResponseinreference/item/types.ts. - Tests — unit tests following existing proxy test pattern (mocked
fetch).
Phase 3a — BFF Upload Proxy and URL Utilities (arda-frontend-app
server-side):
POST /api/image-upload— proxy route that addsAuthorization,X-Tenant-Id,X-Author,X-Request-IDheaders and forwards to BackendPOST /v1/item/image-uploadviaapi-proxy. Returns presigned POST credentials. Note: the backend endpoint is module-scoped (noitemEIdin path); the BFF route mirrors this. See api-proxy-update-to-operations-2.21.md.POST /api/storage/check-url— URL reachability check with SSRF protection (HTTPS-only, private IP rejection, managed storage host rejection). Performs HEAD request with 10s timeout.POST /api/storage/fetch-url— full image fetch proxy for CORS-blocked external URLs. Same SSRF protections. Streams response, max 10 MB, 10s timeout.- Rate limiting — in-memory per-instance, per-tenant sliding-window counter
for
check-urlandfetch-url(configurable default: 30 req/min). - Tests — route handler tests with mocked dependencies.
Phase 3b — BFF CDN Cookie Signing (arda-frontend-app server-side):
POST /api/storage/cdn-cookies— endpoint that extracts tenant from authenticated session, generates CloudFront custom policy scoped to/<tenantId>/*, signs with RSA private key, and sets threeSet-Cookieheaders (CloudFront-Policy,CloudFront-Signature,CloudFront-Key-Pair-Id) with attributesDomain=.arda.cards; Path=/; Secure; HttpOnly; SameSite=Lax.cloudfront-signer.ts— signing utility that loads the private key from AWS Secrets Manager or environment variable. Configurable TTL (default 30 min).- Tests —
CloudFrontSignerTest(unit, mocked Secrets Manager),CdnCookiesRouteTest(integration, test session), tenant scope and isolation tests.
Phase 4a — Design System Component Updates (ux-prototype) and SPA
Integration (arda-frontend-app):
- Introduce minimal lifecycle framework types in
ux-prototype(FD-03) — add only what image upload needs:ValidationResult,FieldError,EditLifecycleCallbacks<T>,EditableComponentProps<T>, and theuseDraft<T>hook. The full framework (useComposedDraft<T>,createCellEditorFactory<T>,EditablePanel<T>, validation composition) is deferred to #77. - Update image components for FD-01 compliance — adapt the 5 image-related
components (excluding
ItemCardEditorwhich is out of scope per FD-06):ImageUploadDialog— adoptEditLifecycleCallbacks<ImageUploadResult>; replace simulated progress timer with indeterminate indicator (FD-04); addUploadErrorstate for production retry.ImageCellEditor— factory accepts typed provider hooks (useImageUpload,useCheckReachability) per FD-01 section 6.3.TypeaheadCellEditor— evaluate hook-style interface vs. currentlookuppromise callback (design decision).ItemGridColumns— expandItemGridLookupsto all lookup fields; add image editor hook wiring to column definitions.ImageFormField— adoptEditableComponentProps<string | null>; addcontextErrorssupport.
- 13 minor component changes deferred to #77 (FD-03).
- Publish new
@arda-cards/design-systemversion — publish to GitHub Packages after component updates pass CI (lint, typecheck, unit tests, Storybook build, VRT). - Update
arda-frontend-appdependency — bump@arda-cards/design-systemto the newly published version. Import image components via@arda-cards/design-system/canary. ITEM_IMAGE_CONFIG— entity-specific configuration constant (1:1 aspect ratio, accepted formats, 10 MB max, 200px min dimension) defined inarda-frontend-app.- TanStack Query integration (FD-01 wiring layer) — add
@tanstack/react-querytoarda-frontend-app. Create TanStack-backed implementations of the typed provider hooks defined by the design system components:useImageUpload(mutation),useCheckReachability(mutation),useFetchExternalImage(mutation),useCdnCookies(query with background refresh). These hooks are the app-side implementations of the FD-01 typed data provider contracts. Components never import TanStack Query — the wiring layer connects TanStack hooks to component callback props via factory functions (AG Grid editors) or direct prop passing (forms). See upload-component-backend-analysis.md and tanstack-component-binding-analysis.md. - External dependencies in
arda-frontend-app— add@tanstack/react-queryand@tanstack/react-query-devtools. Note:react-easy-crop,react-dropzone,browser-image-compression, andheic2anyare dependencies of the design system package, not ofarda-frontend-appdirectly.
Prerequisite: component-preparation
— legacy cleanup (@tanstack/react-table removal) and dev:local tooling
are handled in a separate project that must be merged before this project
begins (FD-07).
Phase 4b — SPA Grid Display and CDN Cookie Lifecycle (arda-frontend-app
client-side):
- CDN cookie lifecycle manager — request cookies at session start, proactive refresh at ~50% of TTL, immediate re-request on tenant switch, 403 recovery with single retry per image request.
- Grid integration —
ImageCellDisplayreplaces inline renderer in item grid column definitions.ImageCellEditorwired for inline edit (double-click / Enter).ImageHoverPreviewon grid thumbnails (~500ms delay). - Loading states — shimmer during load, placeholder + error badge on failure. No layout reflow from async image loading.
Phase 4c — SPA Upload Orchestration and Form Integration (arda-frontend-app
client-side):
- Production
ImageUploadHandler— calls BFFimage-upload(via TanStack mutation), uploads to S3 via presigned POST form, persists CDN URL on entity via existing Redux thunkupdateItem()(FD-05 — entity persist stays in Redux for this project). IncludesUploadingandUploadErrorstates, indeterminate upload progress indicator (FD-04), single-upload-at-a-time enforcement (SPA-FR-020), and always-JPEG output (SPA-FR-021). - Production
ImageReachabilityCheck— direct HEAD with BFFcheck-urlfallback. Direct fetch or BFFfetch-urlfallback for CORS-blocked URLs. - Form integration —
ImageFormFieldwired into Add Item form (optional image field, SPA-FR-022) and Edit Item form (change/remove, SPA-FR-023). Remove image confirmation dialog sendsimageUrl: null. - Copyright acknowledgment — the
ImageUploadDialogdisplays inline copyright text in the confirm footer (“By confirming, you acknowledge that you own or have a license to use this image.”). The separate checkbox gate has been removed from the component; confirm is always enabled (TD-04).
Code Structure (FD-02)
Section titled “Code Structure (FD-02)”All new code in arda-frontend-app must follow the Option C hybrid
structure (FD-02). New directories are created as part of this project;
existing code is not reorganized — that is deferred to
#734.
New directories created by this project:
| Directory | Zone | Contents |
|---|---|---|
src/server/ | bff | New BFF route handlers (image-upload, check-url, fetch-url, cdn-cookies), server-only utilities (cloudfront-signer, ssrf-validator, rate-limiter). Top-level import 'server-only'. |
src/api/ | spa-api | New SPA API functions (image-upload.ts) — plain async fetch() calls to BFF routes. |
src/hooks/image-upload/ | hooks | TanStack mutation hooks, FD-01 typed provider implementations for image upload. |
src/hooks/cdn/ | hooks | useCdnCookies query hook. |
src/providers/ | providers | QueryClientProvider, CdnCookieProvider. |
src/shared/ | shared | (empty initially — shared types remain in src/types/ until #734) |
Existing code left in place (modified, not moved):
| File | Change | Rationale |
|---|---|---|
src/components/items/ItemFormPanel.tsx | Add ImageFormField wiring | Modified in current location |
src/components/items/ grid column defs | Add image cell editor factories | Modified in current location |
src/lib/env.ts | Imported by new src/server/ routes | Not moved — // TODO #734 comment on imports |
src/lib/jwt.ts | Imported by new src/server/ routes | Not moved — // TODO #734 comment on imports |
src/store/ | Untouched | Redux slices remain for client state |
src/lib/ardaClient.ts | Untouched | Existing item CRUD calls remain |
Temporary cross-layer imports: New BFF routes in src/server/ import
env and jwt from src/lib/ (not from src/server/lib/) because those
files haven’t been moved yet. These imports are annotated with
// TODO #734: move to src/server/lib/ and are cleaned up when the full
restructuring executes. ESLint boundary rules for src/server/ should
allowlist src/lib/env and src/lib/jwt during this transition period.
Out of Scope
Section titled “Out of Scope”- Reorganization of existing code — moving
src/lib/contents tosrc/server/lib/,src/shared/, etc. is tracked in #734 and is not part of this project. - AWS infrastructure provisioning — Phase 1 (completed).
- Backend services (presigned POST generation, entity persistence, URL validation) — Phase 2 (separate project).
- API tests in
api-testrepository — Phase 5 (separate project after deployment). - Phase 4d E2E integration testing against live environment — separate deployment activity after all phases are deployed.
- Mobile camera capture UX details — deferred (SD-16).
- Background removal edit operation — deferred (SD-02).
- Bulk CSV image column UX — deferred (SD-03).
- Cross-tenant image sharing — deferred (SD-05).
- S3 object lifecycle/cleanup for orphaned uploads — deferred (NFR-012).
- Accessibility/WCAG requirements — documented as NFR-022 through NFR-025, not in V1.
Constraints
Section titled “Constraints”- Entry criteria from backend: The Backend endpoint contract
(
POST /v1/item/image-uploadrequest/response shape) must be defined before BFF proxy development begins. Live Backend deployment is not required — BFF routes can be developed against mocked responses and verified against the real Backend in Phase 4d. - Entry criteria from infrastructure: Phase 1 must be deployed before CDN cookie signing can be integration-tested (signing key in Secrets Manager, CloudFront trusted key group configured). Unit tests with mocked keys can proceed without deployment.
- api-proxy published before BFF: The
api-proxypackage must be published with the new image upload method before the BFF proxy routes can use it. Usenpm linkfor local development; CI resolves from the registry. - Design system consumption model: Image components live in
@arda-cards/design-system(canary entry point) and are imported as a dependency — never copied intoarda-frontend-app. Any component changes required for production integration must be made inux-prototype, verified with Storybook stories and unit tests, and published as a new package version beforearda-frontend-appcan consume them. - Design system publish before SPA integration: The updated
@arda-cards/design-systempackage must be published to GitHub Packages beforearda-frontend-appcan bump the dependency and use the updated components. Usenpm linkfor local development. - Pattern alignment: Follow existing
arda-frontend-appconventions — BFF route handler structure (JWT verification,UserContextextraction, header injection), component organization, and test patterns (Jest + React Testing Library). - Decisions in parent log: All design decisions must be recorded in the project decision log with sequential ID numbers continuing from the existing series.
- SSRF protection is mandatory: The
check-urlandfetch-urlendpoints must validate target URLs before making outbound requests — HTTPS-only, private IP rejection, managed storage host rejection. This is a security requirement (NFR-009), not optional. - Single upload at a time: Only one image upload may be active per browser
session (SPA-FR-020). The SPA must disable other upload triggers while an
upload is in the
Uploadingstate. - Presigned POST (not PUT): The SPA uploads via presigned POST form fields (not presigned PUT URL) per TD-08. The BFF proxies the credential request; the SPA submits the multipart form directly to S3.
- FD-01: Typed data providers (mandatory): Design system components must
not import
@tanstack/react-query. All backend connectivity uses typed hook interfaces provided by the consuming app. For AG Grid cell editors, factory functions close over typed hooks; column definitions are the assembly point. See tanstack-component-binding-analysis.md. - api-proxy is BFF-only at runtime:
@arda-cards/api-proxyis used at runtime exclusively in Next.js server-side API routes. The SPA calls BFF routes via plainfetch()in the API functions layer (src/api/). SPA code may import type-only re-exports from the package (FD-13) but must not import runtime code or access the Backend API key.
Deliverables
Section titled “Deliverables”api-proxy
Section titled “api-proxy”| # | Deliverable | Location |
|---|---|---|
| 1 | createImageUploadUrl method on ItemProxy | src/reference/item/proxy.ts (modify) |
| 2 | ImageUploadUrlRequest and ImageUploadUrlResponse types | src/reference/item/types.ts (modify) |
| 3 | Unit tests for image upload proxy method | tests/reference/item/proxy.test.ts (modify) |
arda-frontend-app — Phase 3 (BFF)
Section titled “arda-frontend-app — Phase 3 (BFF)”| # | Deliverable | Location |
|---|---|---|
| 4 | image-upload proxy route | src/app/api/image-upload/route.ts (thin re-export) + src/server/routes/image-upload.ts (handler) |
| 5 | check-url reachability route with SSRF protection | src/app/api/storage/check-url/route.ts (thin re-export) + src/server/routes/storage/check-url.ts |
| 6 | fetch-url image fetch proxy with SSRF protection | src/app/api/storage/fetch-url/route.ts (thin re-export) + src/server/routes/storage/fetch-url.ts |
| 7 | Rate limiting middleware for storage routes | src/server/lib/rate-limiter.ts (new) |
| 8 | SSRF validation utility | src/server/lib/ssrf-validator.ts (new) |
| 9 | cdn-cookies signed cookie route | src/app/api/storage/cdn-cookies/route.ts (thin re-export) + src/server/routes/storage/cdn-cookies.ts |
| 10 | CloudFront cookie signing utility | src/server/lib/cloudfront-signer.ts (new) |
| 11 | src/server/index.ts with import 'server-only' | src/server/index.ts (new) |
| 12 | Tests for BFF routes and utilities | src/server/__tests__/ (new) |
ux-prototype — Design System Updates
Section titled “ux-prototype — Design System Updates”| # | Deliverable | Location |
|---|---|---|
| 13 | Minimal lifecycle types: ValidationResult, FieldError, EditLifecycleCallbacks<T>, EditableComponentProps<T> (FD-03) | src/types/canary/utilities/ (new) |
| 14 | useDraft<T> hook for draft management with validation (FD-03) | src/hooks/canary/ or src/types/canary/utilities/ (new) |
| 15 | ImageUploadDialog — indeterminate progress indicator (FD-04), UploadError state, EditLifecycleCallbacks | src/components/canary/organisms/shared/image-upload-dialog/ (modify) |
| 16 | ImageCellEditor — factory accepts typed provider hooks (FD-01) | src/components/canary/atoms/grid/image/ (modify) |
| 17 | ImageFormField — EditableComponentProps<string | null>, contextErrors | src/components/canary/molecules/form/image/ (modify) |
| 18 | ItemGridColumns — expand ItemGridLookups, add image editor hook wiring | src/components/canary/molecules/item-grid/ (modify) |
| 19 | TypeaheadCellEditor — evaluate hook-style interface | src/components/canary/molecules/item-grid/ (modify) |
| 20 | Updated unit tests and Storybook stories | src/components/canary/ (modify) |
| 21 | New package version published to GitHub Packages | package.json version bump, CHANGELOG update |
arda-frontend-app — Phase 4 (SPA)
Section titled “arda-frontend-app — Phase 4 (SPA)”| # | Deliverable | Location |
|---|---|---|
| 22 | @arda-cards/design-system and @arda-cards/api-proxy dependency bumps | package.json (modify) |
| 23 | @tanstack/react-query and devtools dependency | package.json (modify) |
| 24 | QueryClient setup and QueryClientProvider | src/lib/query-client.ts, src/providers/ (new) |
| 25 | SPA API functions layer for BFF calls (new src/api/ layer, FD-02) | src/api/image-upload.ts (new) |
| 26 | TanStack-backed typed provider implementations (FD-01 wiring): useImageUpload, useCheckReachability, useFetchExternalImage | src/hooks/image-upload/ (new, FD-02 feature grouping) |
| 27 | CDN cookie query hook (useCdnCookies) | src/hooks/cdn/ (new, FD-02 feature grouping) |
| 28 | Wiring hooks bridging TanStack providers to component callback props | src/hooks/image-upload/ (new) |
| 29 | ITEM_IMAGE_CONFIG entity-specific configuration constant | src/constants/ (existing directory) |
| 30 | QueryClientProvider setup | src/providers/query-provider.tsx (new, FD-02) |
| 31 | CDN cookie lifecycle provider (context) | src/providers/cdn-cookie-provider.tsx (new, FD-02) |
| 32 | Item grid column definitions updated with image cell components and typed provider factories | src/components/items/ (modify in place) |
| 33 | Add Item form with optional image field | src/components/items/ItemFormPanel.tsx (modify) |
| 34 | Edit Item form with change/remove image | src/components/items/ItemFormPanel.tsx (modify) |
| 35 | Unit tests for hooks, API functions, wiring, and form integration | src/hooks/, src/api/, src/components/ (new test files) |
Success Criteria
Section titled “Success Criteria”api-proxy
Section titled “api-proxy”ItemProxy.createImageUploadUrl()callsPOST /v1/item/image-uploadwith correct path construction and request body. Unit tests pass with mocked fetch.- Response types (
ImageUploadUrlResponse) includeuploadUrl,formFields,objectKey, andcdnUrlfields. - Existing proxy tests continue to pass. Coverage meets 80% threshold.
- Full local checks pass: lint, typecheck, tests, build.
- CHANGELOG updated.
Phase 3 (BFF)
Section titled “Phase 3 (BFF)”- BFF
image-uploadroute proxies request to Backend (viaapi-proxy) with correctAuthorization,X-Tenant-Id,X-Author,X-Request-IDheaders. Response passes through. check-urlperforms HEAD on external HTTPS URL; returnsreachable,contentType,contentLength. Returns 422 for unreachable URLs.fetch-urlfetches and streams external image content. Respects 10 MB max and 10s timeout.- SSRF protection: both
check-urlandfetch-urlreject private IPs, localhost, non-HTTPS schemes, and managed storage URLs with 400. - Rate limiting: exceeding configured threshold returns 429.
- All storage routes return 401 without a valid session JWT.
cdn-cookiesroute issues threeSet-Cookieheaders with correct attributes (Secure,HttpOnly,SameSite=Lax,Domain=.arda.cards).- Cookie policy
Resourcefield is scoped to the authenticated tenant’s prefix (/<tenantId>/*). Tenant ID is extracted from session context, never accepted as a client parameter. CloudFrontSignerTestpasses — policy generation, TTL, RSA signature.- Full local checks pass: lint, typecheck, unit tests, build.
Design System (ux-prototype)
Section titled “Design System (ux-prototype)”- Minimal lifecycle types (
ValidationResult,FieldError,EditableComponentProps<T>,EditLifecycleCallbacks<T>) exported fromtypes/canary(FD-03). useDraft<T>hook implemented and used by image components (FD-03).ImageUploadDialoguses indeterminate progress indicator (FD-04) and supportsUploadErrorstate for production retry.ImageCellEditorfactory accepts typed provider hooks (FD-01).ImageFormFieldadoptsEditableComponentProps, acceptscontextErrors.ItemGridColumnsexpanded with image editor hook wiring.- Updated components pass all existing unit tests and Storybook stories. Default handlers continue to work in Storybook (no TanStack dependency).
- Full local checks pass:
make check(lint + typecheck),make test,make build(Storybook build). - New package version published to GitHub Packages.
- CHANGELOG updated.
Phase 4 (SPA)
Section titled “Phase 4 (SPA)”@arda-cards/design-systemimported at updated version; image components render correctly in the production app viacanaryentry point.- TanStack-backed typed provider hooks (FD-01 implementations) wire correctly to design system component callback props via factory functions (AG Grid editors) and direct prop passing (forms). Upload flow: file pick → preview → crop → confirm → presigned POST → S3 upload → entity updated → CDN thumbnail appears.
useCheckReachability: direct HEAD with BFF fallback on CORS failure.- CDN cookie lifecycle (
useCdnCookies): cookies requested at session start, proactive refresh before expiry, re-request on tenant switch, 403 recovery with retry. - Grid thumbnails load from CDN. Shimmer during load. Placeholder + error badge on failure. Hover preview on ~500ms.
- Double-click / Enter on image cell opens editor modal via factory-injected typed provider hooks; confirm persists and refreshes grid row.
- Add Item form includes optional image field; items saved without image show placeholder.
- Edit Item form supports change and remove image.
- Copyright acknowledgment displayed as inline text in confirm dialog footer.
- Auto-compression applied to oversized images before upload.
- Upload progress indicator visible during
Uploadingstate. - SPA API functions layer (
src/api/) established as the new architectural boundary between TanStack Query hooks and BFF routes. - Full local checks pass: lint, typecheck, unit tests, build.
Cross-Phase
Section titled “Cross-Phase”- component-preparation project merged (prerequisite — legacy cleanup + dev:local tooling).
- No regressions in existing application functionality.
- Full local checks pass for each repository before every commit and PR:
arda-frontend-app:npm run lint,npx tsc --noEmit,npx jest --no-coverage --watchAll=false --forceExit,npm run buildapi-proxy:npm run lint,npm run typecheck,npm run test,npm run buildux-prototype:make check(lint + typecheck),make test,make build
- CHANGELOGs updated for
api-proxy,ux-prototype, andarda-frontend-app.
Reference Documents
Section titled “Reference Documents”-
SPA Specification — primary specification for SPA components and integration
-
BFF Specification — primary specification for BFF routes and CDN cookie signing
-
System Design — structural overview of all sub-systems
-
Phasing — Phase 3/4 definitions,
entry and exit criteria, parallel tracks
-
Backend Specification — Backend endpoint contract consumed by BFF
-
AWS Specification — CDN domain, signing key format, cookie attributes
-
Requirements — FR and NFR traceability
-
CDN Access Control — threat model, cookie security analysis
-
UX Components Specification — 19 components, props, composition hierarchy, design tokens
-
Post-Implementation Specification — deviations D-01 through D-05 from original UX spec
-
External Libraries Assessment — library evaluation (react-easy-crop, react-dropzone, browser-image-compression, heic2any)
-
Scoping — scope decisions SD-01 through SD-16
-
Project Decision Log — TD-01 through TD-14 (system design), PD-01 through PD-04 (infrastructure), FD-01 (typed data providers)
Project-specific analysis documents:
- Upload Component Backend Analysis — connection points, TanStack Query patterns, SPA/BFF wiring proposal
- TanStack Adoption Exploration — strategic analysis: TanStack as platform investment, complex nested data, AG Grid integration, adoption path
- TanStack Component Binding Analysis — Option A vs. C analysis, AG Grid factory pattern, decision FD-01
- Hierarchical Edit Lifecycle —
draft-validate-confirm cycle, validation composition,
useDraft<T> - Abstract Component Lifecycle —
framework design:
useDraft,useComposedDraft,createCellEditorFactory,EditablePanel, validation function convention - UX Prototype Architectural Review — per-component audit against FD-01 + lifecycle framework
- API Proxy Update — Operations 2.21 gap analysis, image upload endpoint path correction
Skills and Guidelines
Section titled “Skills and Guidelines”Coding and Implementation:
- TypeScript Coding Standards — strict mode, ESM packaging, ESLint flat config, Vitest/Istanbul testing
- Implementation Task Workflow — analysis, planning, byproduct generation, session logging phases
Testing:
- Frontend Testing — Jest, React Testing Library, coverage-driven testing
- Mocking Patterns — MSW, mock handlers
Architecture and Patterns:
- Implementation Patterns — pattern index
- BFF Pattern — Next.js API route conventions
Build, Release, and Deployment:
- Dev Workflows — build, test, and deploy commands
- Release Lifecycle — CHANGELOG management, PR ordering for multi-repo projects
Planning:
- Project Planning — structured plan generation from goal files
- Project Decomposition — splitting large plans into sequenced runs
Agent Personas (for team execution):
front-end-engineer— React/Next.js feature implementationtypescript-engineer— TypeScript library/package work (api-proxy)quality-reviewer— code review for standards and idiomssecurity-engineer— SSRF protection reviewprincipal-engineer— architecture decisions and design review
Copyright: (c) Arda Systems 2025-2026, All rights reserved
Copyright: © Arda Systems 2025-2026, All rights reserved