Use when the playbook is designing, implementing, reviewing, or validating a React-admin frontend that talks to a SAFRS or ApiLogicServer backend via the canonical safrs-jsonapi-client adapter lane.
Use this skill whenever the playbook is designing, implementing, reviewing, or validating a React-admin frontend that talks to a SAFRS / ApiLogicServer backend.
This skill exists to stop the frontend from inventing a parallel JSON:API client, a parallel schema format, or ad hoc relationship fetch behavior when safrs-jsonapi-client already provides the intended adapter layer.
For SAFRS / ApiLogicServer frontends, the canonical data-provider lane is:
safrs-jsonapi-client from the approved latest-upstream checkout policy recorded in runtime-bom.md, normally into local app/tmp/safrs-jsonapi-clientcreateDataProvider(...) / createDataProviderSync(...)normalizeAdminYaml(...) schema model as the canonical normalized schema shapedataProviderexecute(resource, params) for SAFRS RPC-style methods or raw JSON service callsDo not hand-roll a separate JSON:API client unless the exception is documented.
If the backend is SAFRS / ApiLogicServer and the frontend is React-admin, safrs-jsonapi-client is the default adapter. Local wrappers may extend it, but they must not replace it.
Any wrapper must preserve the package-compatible normalized record shape:
idja_typeattributesrelationshipsrecord[relationshipName] or record["rel_" + relationshipName]A wrapper that drops ja_type, attributes, relationships, or included hydration is not a compatible wrapper. It is a replacement client.
The playbook's admin.yaml authoring contract is allowed to differ from the package's current raw input shape, but the adapter layer must preserve:
endpointuser_keytab_groupsIf the current package normalizer expects a different raw shape, create a thin adapter that converts the playbook authoring shape into the package input shape. Do not replace the package schema model with a separate local schema system.
filter.q is currently a package backlog item. If the run needs grouped full-text search before upstream support exists, a wrapper is allowed, but it must:
include=...dataProvider boundaryDo not build a search-only mini client that returns a different record shape.
For related-record display:
include=...dataProvider.getOne(...) by idThe runtime must not invent side endpoints for ordinary DB-backed related data that SAFRS already exposes.
execute(resource, params) for custom methodsFor @jsonapi_rpc, SAFRS custom methods, or non-resource JSON service calls, use the adapter's execute(resource, params) method instead of component-level fetch(...).
Frontend components must not call backend APIs directly for delivered app behavior. If the adapter shape is insufficient, extend the adapter or escalate the gap.
The generated app MUST install safrs-jsonapi-client from the approved local
checkout path recorded in runtime-bom.md, normally file:../tmp/safrs-jsonapi-client,
after the playbook materializes the approved latest-upstream checkout into app/tmp/.
Do not use:
codeload snapshotsWhen this skill is used, the run should be able to point to:
runtime-bom.md showing the approved package sourcetab_groups remains authoritative for relationship UIexecute(resource, params) instead of component-level fetchesReject these patterns unless there is a written exception:
{ id, ...attributes }getOne(...)fetch(...) because the adapter was not extendedtab_groups as generator-only decorationadmin.yaml keys not covered by the frontend contractBefore approving a frontend data-access design, answer all of these:
safrs-jsonapi-client not sufficient as the primary adapter?ja_type, attributes, relationships, and included hydration?tab_groups and relationship ordering?qreference/adapter-decision-tree.mdreference/record-shape-contract.mdtemplates/frontend-adapter-exception-template.mdtemplates/frontend-adapter-proof-checklist.mdintegration/PLAYBOOK_INTEGRATION.md