Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@ permissions:
packages: read

jobs:
frontend-fixtures:
name: Frontend image fixture contracts
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v6
with:
python-version: '3.13'
- run: python -m unittest discover -s tests/frontend -p 'test_*.py'

java:
name: ${{ matrix.service }} tests and coverage
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions compose.frontend-demo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ services:
context: ./web/admin
args:
NEXT_PUBLIC_APP_ENV: fixture
NEXT_PUBLIC_ENABLE_PRODUCT_IMAGE_UPLOADS: "true"
gateway:
image: python:3.13-slim
command:
Expand Down
130 changes: 130 additions & 0 deletions docs/frontend/image-verification.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
---
icon: lucide/clipboard-check
---

# Product image verification

The owner selected S3/CloudFront and approved the AWS SDK. Product is deliberately
deferred until its repository exists. This delivery implements the frontend and
records the remaining [backend work](../services/product/images.md). It does not
claim S3 persistence, cloud provisioning or real-service acceptance.

## Executed checks

| App | Passing workflow | Evidence |
| ------- | ------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| Landing | [42603058404](https://github.com/Microsserv52/landing/actions/runs/42603058404) | Formatting, ESLint, types, six unit tests, static build and six desktop/mobile browser cases |
| Store | [42603060813](https://github.com/Microsserv52/store/actions/runs/42603060813) | Same checks, six unit tests and ten desktop/mobile browser cases |
| Admin | [42603940090](https://github.com/Microsserv52/admin/actions/runs/42603940090) | Same checks, six unit tests and six desktop/mobile browser cases, including light/dark screenshots |

All three local pre-commit configurations passed. The static exports and local
Dockerfiles build successfully. No new frontend package or lockfile dependency
was required. The approved AWS SDK is reserved for the future Product backend,
where storage credentials and authorization belong.

Three stdlib HTTP fixture tests passed with:

```bash
python3 -m unittest discover -s tests/frontend -p 'test_*.py'
```

They exercise upload/replace/content reads, alt edits, removal, unchanged other
products, missing CSRF, non-admin access, invalid size/type/dimensions, expired
tickets, wrong-length files and replay/overwrite rejection. These are fixture
contract checks, not proof of real S3 or Product security. The fixture trusts
client dimensions and holds bytes/tickets only in memory.

## Browser evidence

The image suites run against exported files with explicit API fixtures on
Chromium desktop and Pixel 5 profiles. Browser control through the local app was
unavailable in this session, so no manual click-through is claimed. CI provides
the actual browser interactions and screenshot artifacts.

| Element/state | Observed automated outcome |
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| Public image URL | Image decoded with nonzero natural width and the supplied alternative text |
| Failed image fetch | Honest unavailable-image fallback replaced the broken image |
| Legacy product | Optional image field preserved backward compatibility |
| Manage image | Opened the product's dialog for an administrator |
| Empty image dialog | Save disabled until a valid selection |
| Invalid file | Visible JPEG/PNG/size validation message |
| File picker and alternative text | Valid existing project-logo fixture selected and previewed; no invented product photography |
| Save | Requested upload authorization, sent raw PUT with the allowed conditional header and attached the resulting image |
| Replace | New versioned URL returned and the replacement rendered |
| Alt edit | Updated metadata without another file upload |
| Remove / Keep | Confirmation appeared; Keep canceled removal |
| Confirm removal | Image reference removed and dialog closed |
| Cancel / Escape | Dismissed the overlay without saving |
| Theme | Light and Dark dialogs rendered and were captured after settling transitions |
| Mobile | The page stayed within viewport width; dialog content scrolls within its bounded overlay |
| Runtime errors | New suites asserted no uncaught browser page errors |

The first captured screenshots revealed poor visibility of a transparent white
fixture on the paper surface. A neutral gray image background now supports
transparent assets in both themes. Screenshots disable finite transitions to
capture the settled view, rather than a partially faded dialog. Cards use a
consistent crop; the product detail view contains the entire image.

## antislop gate for the image extension

This extends the [full application gate](verification.md#antislop-delivery-gate).
The existing palette, typography, navigation, landmarks and mock-store notices
remain in use. The following records each requirement against the changed UI.

| Rule | Result and evidence |
| ---- | -------------------------------------------------------------------------------------------------------------------------------- |
| R-01 | PASS: existing paper/ink/rust palette retained; gray media background serves transparency visibility |
| R-02 | PASS: new copy scanned for the prohibited punctuation character |
| R-03 | PASS: mobile browser flow passes viewport-width assertion; native file button has a 44px minimum |
| R-04 | PASS: no new decorative icon collection |
| R-05 | PASS: catalog and image-editing tasks retain their existing compositions |
| R-06 | PASS: inherited system controls and editorial product typography |
| R-07 | PASS: no decorative background grid or pattern added |
| R-08 | PASS: no decorative arrows added |
| R-09 | PASS: no promotional badge added |
| R-10 | PASS: settled overlays use normal MUI surfaces, without a blur stack |
| R-11 | PASS: existing image/control radii retained |
| R-12 | PASS: overlay elevation identifies the active editing layer |
| R-13 | PASS: no glow added |
| R-14 | PASS: card repetition supports product comparison; image editing uses a dialog |
| R-15 | PASS: Manage/Save/Remove/Keep image actions name their behavior |
| R-16 | PASS: explanatory copy describes file limits and save behavior |
| R-17 | PASS: dimensions/size limits are implemented validation constraints, not marketing statistics |
| R-18 | PASS: no testimonials or fictional people added |
| R-19 | PASS: existing restrained overlay feedback; screenshot capture settles transitions |
| R-20 | PASS: established catalog identity retained |
| R-21 | PASS: existing working theme selector retained |
| R-22 | PASS: no unrelated illustration added |
| R-23 | PASS: tests reuse the existing project logo as a disclosed upload fixture |
| R-24 | PASS: no ghost navigation links added |
| R-25 | PASS: inherited text colors retain the documented contrast; neutral media surface improves transparent-image visibility |
| R-26 | PASS: browser record covers every new control; unavailable real uploads are disabled with an explicit message |
| R-27 | PASS: invalid file, broken image, pending/error feedback and missing-image states are implemented and exercised where listed |
| R-28 | PASS: no FAQ added |
| R-29 | PASS: only a functional neutral media background added to the existing palette |
| R-30 | PASS: no copied storefront/template branding |
| R-31 | PASS: image-frame, crop/contain and overlay reasons are recorded above |
| R-32 | PASS: native controls, inherited focus ring and Escape behavior verified in the browser suite |
| R-33 | PASS: features live directly in maintained TSX/CSS; no source-patching helper ships |
| R-34 | PASS: Light/Dark image dialogs captured in both desktop/mobile runs |
| R-35 | PASS: builds, actual automated interactions, image decoding and uncaught page-error checks passed |
| R-36 | PASS: no claim of cloud persistence or completed Product security testing |
| R-37 | PASS: existing authorized design direction and dials continue to govern the extension |
| R-38 | PASS: fixture content and future service boundary are explicitly identified |
| R-39 | PASS: labeled native file input, named buttons, alternative text, semantic modal and inherited reduced-motion rules |
| R-40 | PASS: dimensioned images, reserved aspect ratios, lazy catalog images and priority detail media; performance scores not measured |

C-1 PASS: media and overlay choices have stated purposes. C-2 PASS: new control
outcomes are recorded. C-3 PASS: the dialog serves product image management.
C-4 PASS: the new failure, mobile and theme flows were exercised as listed.
C-5 PASS: the fixture/S3 distinction remains explicit.

## Acceptance deferred to Product creation

Implement and validate the saved S3/database contract, backend byte-level image
validation, IAM/CORS, lifecycle cleanup, concurrency protection and CDN caching.
Then run the same UI flows against real services and enable normal uploads.
CDN environment values will be requested at deployment time. Private CodeQL
remains deferred by the owner's earlier decision; the unchanged development-tool
audit findings remain documented in [dependencies](dependencies.md).
5 changes: 5 additions & 0 deletions docs/frontend/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ icon: lucide/panels-top-left

# Frontend applications

The initial implementation is merged. The selected
[product image architecture](product-images.md) adds URL-based rendering and
admin image management, with S3 integration deferred to the future Product
service. Upload controls are enabled only in explicit fixture mode until then.

Three independent Next.js repositories are integrated as Git submodules and
implemented for static CDN export. The local Docker setup serves them on one
origin. **This is an educational mock store: no real payments or transactions
Expand Down
Loading
Loading