diff --git a/README.md b/README.md index a075a33..a9649ae 100644 --- a/README.md +++ b/README.md @@ -89,9 +89,11 @@ API directly and reuse Next.js's fetch cache instead of an extra round trip. ### Collections used by this tenant -All reads are public (`access.read: () => true`) **except `discount-codes`** -(see its own row below); writes are admin-gated in the Payload admin UI at -`payload.mk360.de/admin`. +Most reads are public (`access.read: () => true`); writes are always +admin-gated in the Payload admin UI at `payload.mk360.de/admin`. A growing +subset below is **not** public-read at all (`discount-codes`, `orders`, +`customers`, `number-ranges`, `invoice-settings`) — each row says so and +explains what does have access instead. | Collection (slug) | Used for | Key fields | |---|---|---| @@ -108,23 +110,38 @@ All reads are public (`access.read: () => true`) **except `discount-codes`** | `werkzeuge-cards` | Homepage "Meine Werkzeuge" 3-card grid | `title`, `description`, `icon`, `ctaLabel`, `ctaHref`, `sortOrder` | | `testimonials` | Customer testimonial grids on `/todo-cards`, `/newsletter`, `/challenge` | `quote`, `name`, `role`, `avatar`, `page` (`todo-cards`/`newsletter`/`challenge` — which page's grid this appears in), `sortOrder`. The single-quote "photo band" testimonials on `/not-found` and `/bestellbestaetigung` are a different shape (no avatar/role) and stay hardcoded, not part of this collection. | | `media` | Shared upload collection backing every `image`/`icon`/`thumbnail`/`attachment` field above | `alt` (required for images), `title` (optional display name for download links) | +| `orders` | Persisted checkout orders, `/konto/bestellungen*` | `orderNumber`, `invoiceNumber`/`invoiceIssuedAt`, `correctionInvoiceNumber`/`correctionInvoiceIssuedAt` (see "Invoice PDFs" below), `status` (`received`/`processing`/`shipped`/`delivered`/`cancelled`/`return_requested`/`returned` — the first 4 maintained by hand in the admin, no carrier API; the rest see "Order cancellation & returns"), full address/items/totals snapshot at order time. **Not public-read** — created only via `ORDER_SERVICE_SECRET`, read/updated by admin or the order's own customer | +| `customers` | Storefront accounts — register/login/order-history, a second `auth: true` collection separate from the Payload admin's own `users` login | `customerNumber`, `firstName`/`lastName`/`email`, one default address, `cart` (server-side mirror), `emailVerified` (non-blocking). **Not public-read** — see "Orders & customer accounts" below | +| `number-ranges` | Admin-configurable prefix + running counter for customer/order/invoice numbers — one row per tenant | `customerPrefix`/`customerNext`/`customerPadding`, `orderPrefix`/`orderNext`/`orderPadding`, `invoicePrefix`/`invoiceNext`/`invoicePadding`. **Admin-only**, no frontend read at all — internal to the two `beforeChange` hooks that assign these numbers | +| `email-templates` | Editable subject/heading/body/footer for all 6 transactional emails this shop sends (see "Email templates & Live Preview" and "Status-change emails" below) | `type` (`order-confirmation`/`password-reset`/`order-shipped`/`order-cancelled`/`order-return-requested`/`order-returned`), `subject`, `heading`, `bodyText`, `footerText`. Public-read, has a Live Preview button | +| `invoice-settings` | Structured seller data for invoice PDFs (see "Invoice PDFs" below) — one row per tenant | `sellerName`/`sellerStreet`/`sellerZip`/`sellerCity`/`sellerCountry`/`sellerEmail`, `vatId`, `taxRatePercent` (admin-editable, not hardcoded), `bankDetails`. **Not public-read** — admin or `ORDER_SERVICE_SECRET` | All of the above (except `media`, `users`, `tenants`) are grouped in the Payload admin sidebar under **Commerce** (`products`, `discount-codes`, -`shipping-methods`, `shipping-settings`, `payment-methods`, `trust-badges`, -`cart-trust-badges`) or **Content** (`posts`, `categories`, `legal-pages`, -`werkzeuge-cards`, `testimonials`); `media`/`users`/`tenants` sit under -**Platform** — `users` and `tenants` are hidden from non-super-admins' nav -entirely, and every tenant-scoped collection's own "assigned tenant" field -is hidden from non-super-admins in the edit view (though not yet the list -view's column — see the infra README's Payload CMS section for why that -one's a harder fix). +`orders`, `customers`, `number-ranges`, `email-templates`, +`invoice-settings`, `shipping-methods`, `shipping-settings`, +`payment-methods`, `trust-badges`, `cart-trust-badges`) or **Content** +(`posts`, `categories`, `legal-pages`, `werkzeuge-cards`, `testimonials`); +`media`/`users`/`tenants` sit under **Platform** — `users` and `tenants` +are hidden from non-super-admins' nav entirely, and every tenant-scoped +collection's own "assigned tenant" field is hidden from non-super-admins +in the edit view (though not yet the list view's column — see the infra +README's Payload CMS section for why that one's a harder fix). -Editorial changes (prices, copy, images, toggling a shipping/payment method -on or off) all happen in the Payload admin UI — no code deploy needed. Adding -a *new field* to any collection above requires editing the collection file in -`docker/payload/src/collections/` and a migration, which does need a deploy -of the Payload service. +**What an admin can actually configure without a code deploy, at a +glance:** product/shipping/payment catalog data and `active` toggles, +discount codes, all page content (blog/legal/testimonials/trust badges), +delivery-time disclosure (`shipping-settings`), order/customer/invoice +numbering schemes (`number-ranges`), all 6 email wordings +(`email-templates`, with Live Preview), and invoice seller data + VAT rate +(`invoice-settings`). What still requires a code change: adding a new +*field* to any collection (needs a migration), payment processing itself +(not built), and anything structural in `orders`/`customers` beyond +`status` and the profile fields already exposed on `/konto/profil`. + +Adding a *new field* to any collection above requires editing the +collection file in `docker/payload/src/collections/` and a migration, +which does need a deploy of the Payload service. ### Live Preview