fix(cms): make Partners.logo optional; fix Media read access (public site was broken)
CI Pipeline with Test Management / 🧪 Run Tests & Generate Reports (push) Canceled after 0s
Test Reporting & Gherkin Analysis / 🧪 Run Tests & Generate Reports (push) Canceled after 0s
CI Pipeline with Test Management / 🐳 Docker Integration Tests (push) Canceled after 0s
CI Pipeline with Test Management / 🏗️ Build Docker Image (push) Canceled after 0s
CI Pipeline with Test Management / 📊 Generate Test Summary (push) Canceled after 0s
Test Reporting & Gherkin Analysis / 📊 Analyze Test Coverage (push) Canceled after 0s
Test Reporting & Gherkin Analysis / 🔄 Sync with Linear (push) Canceled after 0s
Test Reporting & Gherkin Analysis / ⚡ Performance Monitoring (push) Canceled after 0s

User request: don't force a logo upload to save a Partner — allow
saving name+url first, logo later. Removed `required: true` from
Partners.ts logo field. The frontend (getPartners(), payload-content.ts)
already filters out logo-less partners before rendering, so this is
safe: a partner without a logo just doesn't show on the public site
yet, nothing breaks.

While verifying this live (create a partner without a logo, check the
public homepage doesn't break), found a real, previously-undetected
bug that predates this change: partner logos never actually loaded on
the public site at all. Payload's default collection read access is
"authenticated users only" (Boolean(user)), and Media.ts never
overrode it — so GET /api/media/file/<name> always 403'd for anyone
not logged into the admin. Next.js's image optimizer (/_next/image)
fetches that URL server-side without forwarding the browser's admin
session cookie, so it always got a 403 back, which it reports as "The
requested resource isn't a valid image" (400) — the <img> silently
rendered as a broken image icon on the homepage the whole time. Fixed
by adding `access: { read: () => true }` to Media.ts — write
operations (create/update/delete) stay admin-only via Payload's
default.

Verified live in the browser: created a Partner with only name+url via
the admin (saved successfully, no required-field error), confirmed it
correctly does NOT appear on the public homepage (no logo yet), then
deleted that test record. Separately, in a fresh unauthenticated tab,
confirmed the existing Partner's logo now actually renders on /hu
(previously a broken image icon) — curl-verified both
/api/media/file/<name> and /_next/image?url=... return 200 without any
auth. Zero console errors. Gate: tsc, lint, unit tests (51 passed),
production build all green.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Do Siki
2026-09-12 00:41:42 +02:00
co-authored by Claude Sonnet 5
parent 02a73b3702
commit d207e5653e
2 changed files with 21 additions and 2 deletions
+13
View File
@@ -17,6 +17,19 @@ export const Media: CollectionConfig = {
admin: {
group: 'Média',
},
// WHY explicit public read access: Payload alapértelmezés szerint minden
// collection read-je csak bejelentkezett usernek engedélyezett
// (defaultAccess = Boolean(user)) — enélkül a /api/media/file/*
// REST route 403-at adott VOLNA vissza kijelentkezve, tehát a publikus
// oldalon a partner logók (Home) sosem töltődtek volna be (a Next.js
// image-optimizer szerver-oldali proxyja sem küld auth cookie-t).
// Valódi böngészős teszttel derült ki (MITHOME-89 óta jelen lévő hiba,
// csak eddig senki nem nézte meg közelről a renderelt <img>-et). Write
// műveletek (create/update/delete) változatlanul csak bejelentkezett
// usernek engedélyezettek (Payload alapértelmezés).
access: {
read: () => true,
},
upload: {
mimeTypes: ['image/*'],
},
+8 -2
View File
@@ -22,7 +22,13 @@ export const Partners: CollectionConfig = {
name: 'logo',
type: 'upload',
relationTo: 'media',
required: true,
// WHY opcionális (felhasználói döntés): így elmenthető egy partner
// név+URL-lel, logó nélkül is — pl. amíg a logó előkészítése
// (remove.bg stb.) még folyamatban van. A frontend (getPartners,
// src/lib/payload-content.ts) eleve kiszűri a logó nélküli
// partnereket, tehát ilyenkor egyszerűen nem jelenik meg a publikus
// oldalon, amíg nincs logó feltöltve — nem törik el semmi.
//
// WHY nincs beépített vágó/áttetszővé tevő szerkesztő: a régi CMS-ben
// ez kliens-oldali canvas-logika volt (scripts/cms-logo-client.js),
// amit tudatosan nem ültettünk át Payload admin komponensként —
@@ -31,7 +37,7 @@ export const Partners: CollectionConfig = {
// PNG-t kell feltölteni, azt egy külső eszközzel (pl. remove.bg)
// előkészítve.
admin: {
description: 'Már kész, átlátszó hátterű PNG-t tölts fel (pl. remove.bg-vel előkészítve) — az admin felület nem vág/forgat/tesz átlátszóvá.',
description: 'Már kész, átlátszó hátterű PNG-t tölts fel (pl. remove.bg-vel előkészítve) — az admin felület nem vág/forgat/tesz átlátszóvá. Logó nélkül is elmenthető a partner, de a publikus oldalon csak logóval jelenik meg.',
},
},
],