Skip to content

feat: operation context for @input/@output [method], object schemas, input.undeclared lint rule - #2

Merged
dskripchenko merged 2 commits into
masterfrom
feat/operation-context-schemas
Oct 1, 2026
Merged

dskripchenko merged 2 commits into
masterfrom
feat/operation-context-schemas

Conversation

@dskripchenko

Copy link
Copy Markdown
Owner

Summary

One controller method may serve many routes: a generic CRUD controller is registered under a controller key per entity, and the fields an action accepts depend on the entity. @input [method] called the method with no arguments, so it could not answer for a particular route — in practice the operation documented no fields at all.

  • OperationContext (Dskripchenko\LaravelApi\Services\OpenApi\OperationContext): version, Api class, controller key, action key, controller class/method, HTTP verb, input/output, the action's options. Passed through the container: declare a parameter typed OperationContext (any name) or any of $version, $controllerKey, $actionKey, $httpMethod. Methods that declare none of them are called exactly as before — backward compatible.
  • A [method] may return a JSON Schema object instead of docblock lines; it goes into the spec as is (constraints, nullable, enum, nested items) and is merged with the other @input lines (required lists united). POST → JSON body; GET → one query parameter per top-level property.
  • @output [method] with the same context and return forms.
  • $tags[] with no child describes a list of scalars.
  • Nested notation fixes: required is kept at every level; a root declared after its children no longer wipes them; nested @output no longer drops flat siblings.
  • Linter input.undeclared (warning): the method visibly validates input (validate(), Validator::make(), validator(), a FormRequest parameter) while its docblock declares no @input. Scoped to validating methods so actions that take nothing are not reported.
/**
 * @input integer $id
 * @input [entityFields]
 */
public function update(Request $request) { /* ... */ }

public function entityFields(OperationContext $context): array
{
    return [
        'type' => 'object',
        'properties' => Entities::find($context->controllerKey)->jsonSchemaProperties(),
    ];
}

Docs: README, docs/{en,ru,de,zh}/docblock-tags.md and linting.md. CHANGELOG under [Unreleased] — intended as 5.11.0 (minor).

Consumer: dskripchenko/laravel-admin needs this release to describe per-resource create/update/action/… inputs.

Test plan

  • vendor/bin/pest — 453 passed (17 new: operation context per controller key, schema pass-through and merge, GET → query params, @output [method], legacy no-arg callables unchanged, scalar binding by name/type, nested required/order/scalar arrays/output siblings, input.undeclared positives and negatives)
  • laravel-admin core suite (952 tests) green against this branch via a local path override
  • CI matrix

🤖 Generated with Claude Code

…ndeclared

Один метод контроллера может обслуживать много маршрутов — обобщённый
CRUD-контроллер регистрируется под ключом на каждую сущность, и набор
полей зависит от маршрута. `[method]` вызывался без аргументов и не мог
ответить за конкретный маршрут; на практике это значило «ни одного поля».

- OperationContext (версия, класс Api, ключ контроллера и действия, класс
  и метод контроллера, HTTP-метод, input/output, опции действия) уходит в
  метод через контейнер: по типу или по именам $version, $controllerKey,
  $actionKey, $httpMethod. Метод без этих параметров вызывается как раньше.
- `[method]` может вернуть JSON Schema объекта — с ограничениями, nullable,
  enum; сливается с остальными @input (POST — JSON-тело, GET — query).
- `@output [method]` с тем же контекстом.
- `$tags[]` без потомка — массив скаляров.
- Вложенная нотация сохраняет required; корень, объявленный после детей,
  их не затирает; вложенный @output не теряет плоских соседей.
- Линтер: input.undeclared — метод валидирует вход и не объявляет @input.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@dskripchenko
dskripchenko merged commit da0876b into master Oct 1, 2026
5 checks passed
@dskripchenko
dskripchenko deleted the feat/operation-context-schemas branch October 1, 2026 21:58
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