Skip to content

feat: per-resource OpenAPI input schemas + spec completeness guard (needs laravel-api 5.11) - #10

Merged
dskripchenko merged 3 commits into
mainfrom
stage-3/openapi
Oct 1, 2026
Merged

dskripchenko merged 3 commits into
mainfrom
stage-3/openapi

Conversation

@dskripchenko

Copy link
Copy Markdown
Owner

Summary

Draft until dskripchenko/laravel-api 5.11.0 is tagged (dskripchenko/laravel-api#2). composer.json requires ^5.11, which Packagist cannot resolve yet, so the PHP CI job fails at composer update until that release exists. Once 5.11.0 is out, re-run CI and mark ready.

One ResourceController serves every resource, so create/update documented no fields at all (the "Which @input fields there are is decided by Resource::fields()" prose). With laravel-api 5.11 a @input [method] receives an OperationContext (controller key = resource slug, action, Api class = panel), so:

  • ResourceController::operationSchema(OperationContext) builds the input schema of one operation on one resource:
    • create / update — from fields() + validationRules($context): types, formats (email/uri/uuid/date/date-time/password), required, nullable, enums from options and in: / Rule::in / Rule::enum, min/max/between/size → minimum/maxLength/minItems by type, flagless regex: → pattern, confirmed → *_confirmation, translatable values per locale, the upload-first {disk, path} of file fields, multiple selects as arrays of enum, defaults and labels;
    • search / summary / tree / export — filters keyed by field (or the {column, value} list form), sortable columns, group_by, exportable columns and registered formats;
    • action — ids and key as an enum of dispatchable actions; reorder; inlineUpdate — editable columns.
  • SettingsController::operationSchema — the values of a settings group.
  • New Http\OpenApi\RulesSchema (rules + fields → object schema) and Http\OpenApi\ResourceOperationSchema.
  • Markup fixes found on the way: system/search documents q and a GlobalSearchResponse; dashboard/reset had no docblock at all; tokenCreate abilities[] typed as strings; action payload is an object. (action ids/key, dashboard/save widgets.* and tokenCreate had already been fixed in 1.31–1.33; the roadmap entries are now marked closed.)

Measured on the test app's fixture resources (9 resources, 1 settings group, 1 screen): operations without any input 65/189 → 47/189 (the rest are GET reads and body-less actions); every create/update now carries the resource's fields; api:lint → 0 issues.

Regression guard (BL-46): tests/Feature/OpenApiSpecCompletenessTest.php — for every registered fixture resource, the documented create/update properties ⊇ the keys of validationRules(); resource-specific inputs present; no $ref to an undefined schema; OpenApiLinter reports nothing, including the new input.undeclared rule (an action that validates input and declares none). Plus a panel test (client panel's resource resolved in its own panel) and RulesSchemaTest unit tests.

Test plan

  • vendor/bin/pest — 965 passed, run locally with laravel-api pointed at the feat/operation-context-schemas branch (temporary local override, not committed)
  • vendor/bin/pint --test, vendor/bin/phpstan analyse — clean
  • CI — expected to fail on dependency resolution until laravel-api 5.11.0 is tagged; re-run after the release

🤖 Generated with Claude Code

dskripchenko and others added 3 commits October 2, 2026 00:42
ResourceController serves every resource, so create/update declared no
fields at all. They now declare `@input [operationSchema]`; laravel-api 5.11
calls it once per route with an OperationContext, and the schema is built
from the resource's fields() and validationRules() (types, formats,
required, nullable, enums, bounds, patterns, confirmed twins, translatable
and file shapes). The same covers the resource-specific input of search,
summary, tree, export, action, reorder, inlineUpdate and settings update.

Also: system/search documents `q` and GlobalSearchResponse; dashboard/reset
gets its docblock; tokenCreate abilities[] and action payload typed.

OpenApiSpecCompletenessTest walks the generated spec: every create/update
documents each validated field, no dangling $ref, api:lint reports nothing
(including input.undeclared). Requires dskripchenko/laravel-api ^5.11.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
# Conflicts:
#	CHANGELOG.md
#	src/Widget/DashboardController.php
@dskripchenko
dskripchenko marked this pull request as ready for review October 1, 2026 22:12
@dskripchenko
dskripchenko merged commit 47ae6bd into main Oct 1, 2026
12 checks passed
@dskripchenko
dskripchenko deleted the stage-3/openapi branch October 1, 2026 22:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant