RetailysUI

Univerzální zobrazení entit z OpenAPI v2

Framework pro automatické generování kompletního uživatelského rozhraní z OpenAPI specifikace. Backend popíše datový model a jeho vizuální metadata — frontend z nich bez jediného řádku konfigurace postaví tabulku i formuláře se sloupci, formátováním, řazením, filtrováním, vazbami a RBAC.

OpenAPI 3.1x-admin-*x-eshop-*JSON:APIUUIDOAuth 2.0 + RBACTypeScriptNext.js

Jaký problém to řeší?

Proč jsme se rozhodli generovat UI automaticky ze schématu místo ručního psaní tabulek a formulářů.

Tradiční přístup

  • Pro každou entitu (Produkt, Kategorie, Objednávka…) se ručně píší sloupce tabulky
  • Každý renderer buňky (měna, datum, štítek) se konfiguruje individuálně
  • Při změně modelu na backendu se musí ručně aktualizovat i frontend
  • Vazby mezi entitami (produkt → kategorie) se řeší ad-hoc
  • Desítky téměř identických stránek s drobně odlišnou konfigurací

Přístup s x-admin-* / x-eshop-*

  • Backend popíše model jednou — v OpenAPI schématu s rozšířeními x-admin-* a x-eshop-*
  • Frontend automaticky vygeneruje tabulku i formulář včetně rendererů
  • Změna modelu na backendu se projeví okamžitě bez úprav frontendu
  • Vazby se řeší deklarativně přes x-admin-relation + sideloading
  • JSON:API envelope s paginací, UUID identifikátory, OAuth 2.0 + RBAC

Co je OpenAPI a proč x-admin-* / x-eshop-*?

Základní pojmy, které je potřeba znát pro pochopení celého systému.

OpenAPI 3.1 specifikace

OpenAPI 3.1 je nejnovější verze standardu pro popis REST API, plně kompatibilní s JSON Schema. Supports type: ["number", "null"] místo nullable: true, UUID formát a další vylepšení.

Rozšíření x-admin-* a x-eshop-*

Standard OpenAPI umožňuje přidávat vlastní rozšíření s prefixem x-. V2 definuje dvě sady: x-admin-* pro administrační UI a x-eshop-* pro storefront.

x-admin-resource

Metadata entity — název, popis, ikona, operace, RBAC politiky

x-admin-datagrid

Konfigurace tabulky — sloupce, řazení, hromadné akce, filtry

x-admin-form

Konfigurace formuláře — layout, skupiny polí, widgety, závislosti

x-admin-enum

Barvy a popisky pro hodnoty výčtu — štítky, stavy

x-admin-relation

Vazba na jiný resource — sideloading přes ?include=

x-eshop-*

Storefront: display, facety, SEO, badges, prominence

Jak začít

Tři kroky k zobrazení libovolné entity — od schématu po vykreslenou tabulku.

1

Připravte OpenAPI 3.1 schéma s x-admin-* rozšířeními

{
  "Product": {
    "type": "object",
    "x-admin-resource": {
      "label": "Product", "labelPlural": "Products",
      "displayField": "name", "icon": "ShoppingBag01"
    },
    "x-admin-datagrid": {
      "columns": [
        { "field": "name", "sortable": true, "isRowHeader": true },
        { "field": "price", "renderer": "currency", "align": "right" }
      ]
    },
    "properties": { ... }
  }
}
2

Backend vrací JSON:API envelope

// GET /api/v2/products?include=categories&page=1&pageSize=10
{
  "data": [{ "id": "a1b2c3d4-...", "name": "Notebook", ... }],
  "meta": { "total": 26, "page": 1, "pageSize": 10, "pageCount": 3 },
  "links": { "self": "/api/v2/products?page=1", "next": "...", ... },
  "included": { "categories": [{ "id": "c0a80101-...", "name": "Electronics" }] }
}
3

Použijte EntityTable a EntityForm

<EntityTable
  schemaUrl="/api/v2/schema"
  dataUrl="/api/v2/products"
  schemaName="Product"
/>

<EntityForm
  schemaUrl="/api/v2/schema"
  schemaName="Product"
  onSubmit={(data) => { /* save */ }}
/>

Architektura systému v2

Jak funguje celý systém od OpenAPI specifikace až po vykreslenou tabulku — krok po kroku.

#1

OpenAPI 3.1 specifikace

Backend publikuje specifikaci s x-admin-resource, x-admin-datagrid a x-admin-form. Datagrid sloupce jsou definovány na úrovni schématu, ne per-property. Vazby používají x-admin-relation s konvencí /api/v2/{resource}.

načtení a parsování
#2

Schema Parser

parseSchemaProperties() normalizuje OAS 3.1 typy (type arrays → primary + nullable).parseAdminDatagrid() merguje datagrid columns s property daty.extractIncludes() generuje ?include= parametr pro sideloading.

generování sloupců
#3

Admin Renderers

createAdminCellRenderer() factory bere ParsedAdminColumn a vrací render funkci. Importuje base renderery (currency, badges, tags, relation) z sdílené vrstvy.

sestavení
#4

EntityTable + EntityForm → DataTable

EntityTable orchestruje schema parsing, data fetch s JSON:API envelope + sideloading, a předá vše DataTable. EntityForm generuje formuláře z x-admin-form s tabs/wizard layoutem.

Příklad transformací:

categoryId: "c0a8..." → Elektronikaprice: 2499 → 2 499,00 CZKstatus: active → Active

Datové typy a renderery

Přehled podporovaných datových typů a jejich automatické mapování na vizuální komponenty.

PropTypeDefaultDescription
stringText-Prostý text. Výchozí zobrazení pro všechny řetězce.
string + dateDate-Formátované datum v českém formátu (např. '15. led 2025').
string + date-timeDateTime-Datum a čas (např. '15. led 2025, 10:30').
string + uuidUUID-UUID identifikátor — skrytý ve výchozím stavu.
string + uriLink-Klikatelný odkaz, který se otevře v novém panelu prohlížeče.
string + emailEmail link-Odkaz typu mailto: pro odeslání e-mailu.
string + enumBadge-Barevný štítek (Badge) s popisky z x-admin-enum.
number + currencyCurrency-Měnový formát (např. '2 499,00 CZK'). Vyžaduje renderer='currency' a currencyField.
[number, null]Nullable Number-OAS 3.1 nullable — type array obsahující 'null'.
booleanAno / Ne-Zobrazí 'Ano' nebo 'Ne' s barevným rozlišením.
array[string]Tag list-Každá položka pole se zobrazí jako samostatný štítek (Badge).
string + relationRelation-Sideloading přes ?include= — UUID → display name.

Referenční příručka rozšíření x-admin-* / x-eshop-*

Kompletní přehled všech rozšíření OpenAPI specifikace v2.

x-admin-resource — metadata entity

PropTypeDefaultDescription
label*string-Název entity v jednotném čísle.
labelPlural*string-Název entity v množném čísle.
displayField*string-Hlavní zobrazovací pole (e.g. 'name').
iconstring-Identifikátor ikony.
descriptionstring-Popis entity.
operationsOperation[]-Vlastní operace (duplicate, archive, ...).
policies{ read?, write?, delete? }-RBAC scope requirements.

x-admin-datagrid — konfigurace tabulky

PropTypeDefaultDescription
columns*Column[]-Definice sloupců s field, label, sortable, renderer, ...
defaultSort{ field, direction }-Výchozí řazení.
batchActionsAction[]-Hromadné akce (delete, archive, ...).
filtersRecord<string, Filter>-Konfigurace filtrů.

x-admin-form — konfigurace formuláře

PropTypeDefaultDescription
layout'single' | 'tabs' | 'wizard'-Rozložení formuláře.
groupsGroup[]-Skupiny polí s name, label, order, fields[].
fieldsRecord<string, Field>-Konfigurace polí — widget, placeholder, helpText, dependency.

x-admin-relation — vazba na resource

PropTypeDefaultDescription
resource*string-Název resource (e.g. 'categories'). Konvence: /api/v2/{resource}.
displayField*string-Pole na related entity, které se zobrazí.
type'belongsTo' | 'hasMany' | 'manyToMany'-Typ vztahu.

x-eshop-* — storefront rozšíření

PropTypeDefaultDescription
x-eshop-displayProperty-level-prominence (hero/primary/secondary/hidden), badges[], visibility[]
x-eshop-facetsSchema-level-Facetové filtry — type (term/range/boolean), widget, sort
x-eshop-seoSchema-level-SEO šablony — titlePattern, metaDescription, ogImage

Vazby mezi entitami

V2 používá sideloading přes ?include= parametr místo N+1 fetchů.

Product
id: "a1b2c3d4-..."
name: "Notebook HP"
categoryId: "c0a80101-...001"
x-admin-relation
Category
id: "c0a80101-...001"
name: "Elektronika"
slug: "electronics"

Jak to funguje v v2

Pole categoryIdx-admin-relation s resource: "categories".

  • Parser zavolá extractIncludes()["categories"]
  • Fetch: GET /api/v2/products?include=categories
  • Response: included.categories obsahuje sideloaded data
  • Renderer mapuje UUID → display name

Výhody sideloadingu

  1. Jeden HTTP request místo N+1 fetchů
  2. Konzistentní data v rámci response
  3. Optimalizace na backendu (eager loading)
  4. Client řídí, co potřebuje přes ?include=

Živá ukázka

EntityTable a EntityForm generované z OpenAPI v2 specifikace s JSON:API responses a UUID identifikátory.

Product — tabulka (16 vlastností, UUID, vazba na Category)

Loading schema...

Category — jednoduchá entita (4 vlastnosti)

Loading schema...

Backend a API endpointy v2

JSON:API formát, UUID identifikátory, bracket filtrování, sideloading.

REST endpointy

GET/api/v2/schemaOpenAPI 3.1 specifikace se všemi x-admin-* a x-eshop-* rozšířeními
GET/api/v2/{resource}JSON:API list s paginací, sort, filter, include
GET/api/v2/{resource}/{id}Detail jednoho záznamu (UUID)
POST/api/v2/{resource}Vytvoření nového záznamu
PUT/api/v2/{resource}/{id}Úprava záznamu
DELETE/api/v2/{resource}/{id}Smazání záznamu

Query parametry

PropTypeDefaultDescription
pageinteger1Číslo stránky.
pageSizeinteger10Počet záznamů na stránku.
sortstring-Řazení: 'name' (asc), '-price' (desc).
includestring-Sideloading: 'categories' nebo 'categories,tags'.
filter[field][op]string-Filtr: filter[status][eq]=active, filter[price][gte]=100.

Surové OpenAPI 3.1 schéma

Kompletní specifikace včetně všech x-admin-* a x-eshop-* rozšíření.

Stav implementace v2

Přehled hotových funkcí v2 frameworku.

Core v2

OpenAPI 3.1 — type arrays, nullable, UUID format
x-admin-resource — metadata, operace, RBAC policies
x-admin-datagrid — schema-level sloupce, defaultSort, batchActions
x-admin-form — tabs/wizard/single layout, skupiny, dependency
x-admin-relation — sideloading přes ?include= (žádné N+1)
x-eshop-* — display, facety, SEO, badges, prominence
JSON:API envelope — data, meta (pagination), links, included
UUID identifikátory — string format uuid místo integer
Auth + RBAC — OAuth 2.0 context, scope-based access control
API client — authenticated fetch s Bearer token a tenant header

Komponenty

EntityTable — v2 API, sideloading, JSON:API parsing, admin datagrid
EntityForm — schema-driven formuláře s react-hook-form
Admin renderers — factory s ParsedAdminColumn vstupem
Storefront renderers — product price, badge evaluation

Plánovaná rozšíření

Server-side stránkování — integrace s DataTable pagination
Real OAuth 2.0 — PKCE flow, token refresh, login UI
Napojení na reálný backend — přechod ze statických dat na DB

Zdrojové soubory

Přehled všech souborů frameworku v2.

PropTypeDefaultDescription
lib/openapi/types.tsTypy-OAS 3.1 typy, x-admin-*, x-eshop-* interfaces, ParsedProperty, API response typy.
lib/openapi/parser.tsParser-Sdílený základ: humanizeFieldName, normalizeType, parseSchemaProperties.
lib/openapi/schema.tsSchéma-OpenAPI 3.1 spec s Product a Category, x-admin-*, x-eshop-*.
lib/openapi/cell-renderers.tsxRenderery-Base renderery: date, currency, badge, tag, relation, image, boolean.
lib/openapi/admin/parser.tsAdmin parser-parseAdminResource, parseAdminDatagrid, toDataTableColumns, parseAdminForm.
lib/openapi/admin/renderers.tsxAdmin renderers-createAdminCellRenderer factory s ParsedAdminColumn vstupem.
lib/openapi/storefront/parser.tsStorefront parser-parseEshopFacets, filterByVisibility, sortByProminence, resolveSeoTemplate.
lib/openapi/storefront/renderers.tsxStorefront renderers-renderProductPrice, evaluateBadges.
lib/auth/types.tsAuth typy-AuthUser, TokenPair, AuthSession, AuthAction.
lib/auth/auth-context.tsxAuth context-AuthProvider, useAuth hook, mock dev user.
lib/auth/rbac.tsRBAC-hasAccess, hasScope, canRead, canWrite, canDelete.
lib/api/client.tsAPI klient-createApiClient s Bearer + tenant headery, CRUD metody.
lib/api/types.tsAPI typy-QueryParams, buildQueryString.
lib/mock-data/products.tsData-5 kategorií + 26 produktů s UUID a null.
components/.../entity-table.tsxKomponenta-EntityTable — v2 API, sideloading, admin datagrid.
components/.../entity-form.tsxKomponenta-EntityForm — schema-driven formuláře s react-hook-form.
app/api/v2/schema/route.tsAPI route-GET /api/v2/schema.
app/api/v2/[resource]/route.tsAPI route-GET + POST /api/v2/{resource} s JSON:API envelope.
app/api/v2/[resource]/[id]/route.tsAPI route-GET + PUT + DELETE /api/v2/{resource}/{id}.