Br install and migrate
Skill Lonsdale201/wp-agent-skills/better-route/br-install-and-migrate
Install better-route from Packagist or migrate a WordPress integration to better-route 1.1. Use when adding better-route/better-route, changing the Composer constraint to ^1.1, upgrading from 1.0 or pre-1.0 releases, diagnosing new 403 route responses, migrating atomic idempotency schema, or reviewing 1.1 behavior changes in routing, Resource CRUD, CORS, ETag, rate limiting, JWT/JWKS, OpenAPI, and WooCommerce routes.From its SKILL.md
npx -y skills add Lonsdale201/wp-agent-skills --skill br-install-and-migrateAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- 21 stars21 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
- runs commandsInstructs the agent to run 5 commands, including `composer require better-route/better-route:^1.1` and 4 more.
SKILL.md
9.0 KB, ~1.9k tokens by cl100k_base, as published. Nobody here has run it
better-route: install and migrate to 1.1
Install
Require the stable 1.1 line directly from Packagist:
composer require better-route/better-route:^1.1
composer show better-route/better-route
Use PHP 8.1 or newer. Do not add a VCS repository unless intentionally consuming a fork or unreleased branch.
Register routes during rest_api_init:
use BetterRoute\Router\Router;
add_action('rest_api_init', static function (): void {
$router = Router::make('myapp', 'v1');
$router->get('/ping', static fn (): array => ['pong' => true])
->publicRoute();
$router->register();
});
1.1 migration checklist
Treat these as consumer-visible changes when moving from ^1.0 to ^1.1.
Routing
- Add
permission(),protectedByMiddleware(), orpublicRoute()to every raw Router route. In 1.1 omitted intent deniesGETandOPTIONStoo, not only writes. - Register only during
rest_api_init. Registration outside the hook or afalseresult from WordPress now throws clearly. - Use WordPress route regex such as
/(?P<id>\d+), not{id}. - Review one-parameter handlers: an untyped parameter receives the WP request; a
RequestContext-compatible type receives the context. - Keep route
argsvalidation cheap and side-effect free because WordPress performs it beforepermission_callback.
Identity, cache, and throttling
- Expect default cache, idempotency, and rate-limit keys to use a native logged-in WordPress user even when no auth middleware populated
attributes['auth']. - Expect structured, recursively canonicalized keys and fingerprints. Do not depend on old delimiter-concatenated key strings.
- Use
WpObjectCacheRateLimiteronly with a persistent external object cache that supports atomicwp_cache_incr(). - Use the default
TransientRateLimiteronly where MySQL named locks are available; it now serializes the transient read/modify/write instead of racing. - Read
Retry-Afteras well asX-RateLimit-*on429responses.
Idempotency and optimistic locking
- Re-run
WpdbAtomicIdempotencyStore::installSchema()during deployment/activation. The 1.1 schema addsreservation_tokenand migrates an existing table. - Do not release an uncertain atomic reservation after a throwable unless duplicate execution is demonstrably safe.
releaseOnThrowablenow defaults tofalse. - Keep idempotency keys at or below the configured
maxKeyLength(default 200) and printable ASCII. - Store data-only responses. Better Route serializes no arbitrary PHP classes;
WP_REST_Responseis converted to a safe Better Route response and returnedWP_Errorvalues are not stored. - Understand that optimistic locking serializes cooperating Better Route writers with a MySQL advisory lock. External writers must use the same protocol or a storage-level conditional update.
Resource DSL
- Treat omitted
allow()as full CRUD and explicitallow([])as no routes. Unsupported action names now throw. - Never call both
sourceCpt()andsourceTable()on one Resource; 1.1 rejects the combination. - Review CPT exposure. Default reads only allow a publicly viewable post type and visible status; password/private read data fails closed.
- Avoid arbitrary per-item
cptVisibilityPolicy()callbacks on large datasets. Accurate visible totals require scanning all matched pages; prefer a query-level repository condition. - Keep
defaultPerPage <= maxPerPage; validation is performed on final registration state, so fluent setter order no longer changes validity. - Expect custom-table null payloads to become SQL
NULL, default ordering to use the primary key, and non-primary sorts to add the primary key as a stable tie-breaker. - Strict list parsers accept WordPress global REST parameters
_locale,_fields,_embed,_envelope, and_jsonp; other unknown parameters still fail.
CORS, ETag, errors, and telemetry
- Attach
CorsMiddlewareto matched routes and explicitly mark any rawOPTIONSroute public. The 1.1 WordPress bridge handles preflight before dispatch and replaces core CORS headers for those routes. - Validate configured CORS origins/methods/header names; wildcard origin plus credentials remains invalid.
- Expect ETag matching to support weak validators, comma-separated validators, and
*;WP_REST_Responsestatus/data/cache headers are preserved.WP_Errorand non-2xx responses are skipped. - Pass response headers through the new
ApiException(..., headers: [...])argument when required. Status, header names, and CR/LF values are validated. - Do not expect arbitrary
WP_Errordata in client details. Only the allowlisted core validationparamsmap is exposed. - Treat audit/metric delivery as best-effort. Sink failures no longer replace a successful API response or mask the application exception.
JWT and JWKS
- When
maxLifetimeSecondsis configured, issue bothiatandexp; missing either claim fails verification. - Keep JWKS URLs HTTPS.
HttpJwksProviderrequireswp_safe_remote_get()with bounded redirect/body settings. - Expect unknown-
kidrefreshes to be throttled by MySQL lock plus transient cooldown. A failed refresh preserves last-known-good cached keys.
OpenAPI
- Let executable route
argsgenerate path/query parameters; use explicitmeta.parametersonly to override the samein+namepair. - Use
meta(['openapi' => ['include' => false]])for route exclusion. - Expect explicit
meta.responsesto replace defaults at the same status, andOPTIONSto document204without a response body. - Provide
<Resource>Responseenvelope schemas for Resource create/update and for get whenuniformEnvelope(true)is enabled.
WooCommerce
- Configure Woo idempotency with
AtomicIdempotencyStoreInterface. In WordPress, the registrar installs/migrates and reusesWpdbAtomicIdempotencyStore; schema failure is surfaced instead of falling back to request-local memory. - Treat omitted
actions[resource]as full CRUD and explicit[]as disabled. Invalid action names throw. - Expect strict payload types and unknown nested-key rejection. Order payloads are fully validated before writes and create/update run in a Woo transaction.
- Keep product
priceread-only; sendregular_priceorsale_price. - Do not send
usernameon customer update; username changes are rejected. - Require customer
emailand couponcodeon create. Coupon code uniqueness is checked on create and update under a named lock. - Paginate list endpoints.
per_page > maxPerPagereturns400 validation_failed; it is not silently clamped. - Expect stable ID tie-break ordering and request expensive customer
orders_count/total_spentfields explicitly on lists.
Older migrations still in force
When upgrading from pre-1.0, also preserve these established contracts:
- JWT
expis required by default. WpClaimsUserMapperdoes not mapsub, email, or login by default; opt in only with an issuer-safe mapping.- Granted-scope wildcards are opt-in.
- Custom-table Resource permissions deny by default.
- The OpenAPI document endpoint defaults to
manage_options. - CORS wildcard origin cannot be combined with credentials.
- Woo money fields are decimal strings, product
priceis read-only, and HPOS absence is503 hpos_requiredfor order routes.
Verify
Run the package checks and then live REST smoke tests against the host stack:
composer test
composer analyse
composer cs-check
Smoke at minimum: anonymous/public and denied routes, authenticated reads/writes, CORS preflight, conditional ETag 304, rate-limit 429 headers, repeated/concurrent idempotent writes, OpenAPI generation, Resource pagination/visibility, and Woo writes with HPOS enabled.
Related skills
- Use
br-routesfor handler and permission details. - Use
br-atomic-idempotencyandbr-optimistic-lockingfor write safety. - Use
br-resource-cpt,br-resource-table, andbr-woo-routesfor migration details by integration. - Use
br-cors-public-client,br-rate-limiting,br-openapi, andbr-jwks-jwt-authfor subsystem configuration.
References
- Official documentation: https://lonsdale201.github.io/better-docs/docs/better-route/agents
- Official documentation: https://github.com/Lonsdale201/better-route
- Verified source paths:
README.mdcomposer.jsonsrc/Router/Router.phpsrc/Middleware/Write/WpdbAtomicIdempotencyStore.phpsrc/Integration/Woo/WooRouteRegistrar.php
What ships with it: 1 file
229 B alongside SKILL.md
agents/
- openai.yaml229 B